django-casdoor-auth
A Django app that lets users sign in to your Django site with Casdoor (OAuth 2.0 authorization code flow), built on casdoor-python-sdk.
- The
stateparameter is random, stored in the session and checked on the callback (no login CSRF). - The access token's signature, expiry and audience are verified with your application's certificate, and only users of the configured organization are accepted.
- Each Django user is linked to a Casdoor user by its immutable Casdoor ID, so renaming a user in Casdoor keeps the same Django account, and nobody can take over an existing Django account (e.g. a local
adminsuperuser) by signing up in Casdoor with the same name. - Users created through Casdoor get an unusable password: they can only sign in through Casdoor.
Requires Python 3.10+ and Django 4.2+.
Install
pip install django-casdoor-auth
Configure
Add casdoor_auth to INSTALLED_APPS in settings.py (it needs django.contrib.auth and django.contrib.sessions):
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"casdoor_auth",
]
Then add your Casdoor application:
CASDOOR_CONFIG = {
"endpoint": "https://door.casdoor.com",
"client_id": "<client-id>",
"client_secret": "<client-secret>",
"certificate": """-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----""",
"org_name": "casbin",
"application_name": "app-example",
}
LOGIN_REDIRECT_URL = "/"
| Key | Required | Description |
|---|---|---|
endpoint |
Yes | Casdoor server URL, e.g. http://localhost:8000 |
client_id |
Yes | Client ID of the Casdoor application |
client_secret |
Yes | Client secret of the Casdoor application |
certificate |
Yes | Public certificate (PEM) of the application's cert in Casdoor, used to verify access tokens |
org_name |
Yes | Organization of the application; users of other organizations are rejected |
application_name |
Yes | Name of the Casdoor application |
front_endpoint |
No | Casdoor URL that browsers use, if it differs from endpoint (e.g. endpoint is an internal address) |
scope |
No | OAuth scope, read by default |
Other settings:
| Setting | Default | Description |
|---|---|---|
REDIRECT_URI |
the callback view's URL | Callback URL sent to Casdoor. Set it when Django is behind a proxy and cannot build its public URL |
LOGIN_REDIRECT_URL |
/accounts/profile/ |
Where users go after signing in, unless the login URL has a safe ?next= |
LOGOUT_REDIRECT_URL |
/ |
Where users go after signing out |
CASDOOR_CREATE_USERS |
True |
Create a Django user the first time a Casdoor user signs in. When False, Casdoor users without a Django account are rejected |
CASDOOR_LINK_EXISTING_USERS |
False |
Let a Casdoor user sign in as an existing Django user of the same name that has a password. Only enable it if every name in your Casdoor organization is trustworthy |
In the Casdoor application, add the callback URL (e.g. https://example.com/casdoor/callback/) to Redirect URLs.
Run the migrations to create the table that links Django users to Casdoor users:
python manage.py migrate
Routes
from django.urls import include, path
urlpatterns = [
# ...
path("casdoor/", include("casdoor_auth.urls")),
]
| URL | Name | Description |
|---|---|---|
/casdoor/login/ |
casdoor_sso |
Redirects to Casdoor. Accepts ?next= to return to a page afterwards |
/casdoor/callback/ |
callback |
Casdoor redirects here; signs the user in |
/casdoor/logout/ |
casdoor_logout |
Signs the user out of Django (POST only, like Django's LogoutView) |
<a href="{% url 'casdoor_sso' %}?next={{ request.path|urlencode }}">Sign in with Casdoor</a>
<form method="post" action="{% url 'casdoor_logout' %}">
{% csrf_token %}
<button type="submit">Sign out</button>
</form>
After signing in, request.user is the Django user and request.session["user"] holds the claims of the Casdoor access token (name, display name, email, roles, permissions, ...).
Upgrading from 1.x
- Run
python manage.py migrate. - Users that 1.x created are linked to their Casdoor user the next time they sign in. A Django user with a real password is not taken over by a Casdoor user of the same name unless
CASDOOR_LINK_EXISTING_USERS = True. - The logout view only accepts POST.
- The helper views in
casdoor_auth.userare removed; call casdoor-python-sdk directly instead.
Development
pip install -e . black ruff
python -m django test --settings=tests.settings --pythonpath=.
black casdoor_auth tests && ruff check casdoor_auth tests
License
Metadata
Release files for django-casdoor-auth 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_casdoor_auth-2.0.0.tar.gz | 21.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_casdoor_auth-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.8 kB
Release files / django_casdoor_auth-2.0.0.tar.gz
| Download URL | django_casdoor_auth-2.0.0.tar.gz |
|---|---|
| Size | 21.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3c6e21388bee480659a3190651aebda5ca6e5bb27b287e86ff35a1d5c73f8eb2
|
|
BLAKE2b-256 checksum How to use checksums |
5385f7da16c5fea0a15b6c0e7789e4afa1e023713596636253b4cb8423dcf3e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.7
|
Release files / django_casdoor_auth-2.0.0-py3-none-any.whl
| Download URL | django_casdoor_auth-2.0.0-py3-none-any.whl |
|---|---|
| Size | 19.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f723b81c589ae78b15c1c5e3a836dd00ca245ae2b697ade8a5c0fe7a0ba53b48
|
|
BLAKE2b-256 checksum How to use checksums |
870f0a1f63ec43c225f0290e3bd94c457ceca30c82ec0d43ad4c0fa41270bcc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.7
|