HopID Client for Django
django-hopid is a lightweight Django library that simplifies OpenID Connect (OIDC) authentication with an authorization server powered by django-oauth-toolkit
. It offers decorators, utility functions, URLs, and template tags to streamline secure login integration.
📚 Table of Contents
✅ Features
- 🧷 OpenID Connect Authorization Code flow with PKCE and nonce support
- 🔐 Secure token exchange and ID token verification (including issuer, nonce, and access token hash checks)
- 🤝 Seamless user login or creation using the access token
- 🌈 Template tag for styled login button
- ⚖️ Built-in URL routes for callback and logout
- ✨ Minimal configuration, no third-party dependencies
🛠️ Installation
pip install django-hopid
Add to INSTALLED_APPS
(for templates):
INSTALLED_APPS = [
...,
'django_hopid',
]
Ensure request
is in template context:
TEMPLATES = [
{
'OPTIONS': {
'context_processors': [
...,
'django.template.context_processors.request',
],
},
},
]
🚀 Quick Start
1. Configure settings
Add the following to your settings.py
:
HOPID_URL = "https://auth.example.com"
HOPID_CLIENT_ID = "your-client-id"
HOPID_CLIENT_SECRET = "your-client-secret"
HOPID_CLIENT_URI = "https://yourapp.example.com"
2. Include URLs
In your app's urls.py
, include HopID routes:
from django.urls import path, include
urlpatterns = [
path("id/", include("django_hopid.urls")),
]
This provides:
/id/callback/
for OIDC callback/id/logout/
for logout/id/login/
for login (accepts GET parameters:next
- redirect to after login,method
- can beemail
orstudent_id
)
2. (Alternative) Use the callback decorator
Create your callback view:
from django.shortcuts import render
from django_hopid.decorators import hopid_callback
@hopid_callback()
def hopid_callback_view(request, *args, **kwargs):
user = kwargs.get("user")
return render(request, "home.html", {"user": user})
4. Use the login button tag
In any template:
{% load hopid_tags %}
{% hopid_login_button %}
This renders a styled login button based on your template:
<a href="https://auth.example.com/o/authorize/?..." class="hopid-login-button">
Login with HopID
</a>
Or use {% hopid_login_url %}
manually in href
.
5. Protect API
from django.http import JsonResponse
from django_hopid.decorators import hopid_protected
@hopid_protected
def protected_view(request):
return JsonResponse({
"message": f"Hello {request.user.username}, you're authenticated!",
})
⚙️ Advanced Usage
Custom callback response handling
Pass a custom response=
to the decorator to override error handling:
@hopid_callback(response=my_error_view)
def hopid_callback_view(request, user=None, error=None):
if error:
return render(request, "error.html", {"error": error})
return render(request, "home.html", {"user": user})
Use login URL in views
If you want to build your own login redirect view:
from django.shortcuts import redirect
from django_hopid.utils import get_hopid_login_url
def login_view(request):
return redirect(get_hopid_login_url(request))
Logout integration
Logout is handled via:
from django.contrib.auth import logout as django_logout
from django.shortcuts import redirect
from django_hopid.utils import get_hopid_logout_url
def logout_view(request):
django_logout(request)
return redirect(get_hopid_logout_url(request))
Or use the built-in route /auth/logout/
.
📄 License
This project is licensed under the MIT License. See the LICENSE file for details.
🤝 Contributing
Contributions are welcome! Open issues or pull requests on Git.