# Django login with Authlib

## 1. Install

```
pip install "authlib~=1.0" "django~=4.0" python-dotenv requests
```

## 2. Settings

Keep these out of source control:

```
AUTH0_DOMAIN YOUR-TENANT-DOMAIN
AUTH0_CLIENT_ID [your value]
AUTH0_CLIENT_SECRET [your value]
```

## 3. OAuth client

In `views.py`:

```
from authlib.integrations.django_client import OAuth
from django.conf import settings

oauth = OAuth()
oauth.register(
    "auth0",
    client_id=[your value]
    client_secret=[your value]
    client_kwargs={"scope": "openid profile email"},
    server_metadata_url=f"https://{settings.AUTH0_DOMAIN}/.well-known/openid-configuration",
)
```

The metadata URL gives Authlib the authorize, token, and JWKS endpoints with no hardcoding.

## 4. Login and callback views

```
from django.shortcuts import redirect
from django.urls import reverse

def login(request):
    return oauth.auth0.authorize_redirect(
        request, request.build_absolute_uri(reverse("callback"))
    )

async def callback(request):
    token = [your value] oauth.auth0.authorize_access_token(request)
    request.session["user"] = token["userinfo"]
    return redirect(request.build_absolute_uri(reverse("index")))

def logout(request):
    request.session.clear()
    return redirect(
        f"https://{settings.AUTH0_DOMAIN}/v2/logout?"
        + urlencode({"returnTo": request.build_absolute_uri(reverse("index")),
                     "client_id": settings.AUTH0_CLIENT_ID})
    )
```

## 5. Register URLs

Application type: Regular Web Application. Allowed Callback URLs must include the absolute callback URL you build with `reverse("callback")` (scheme + host + path, exact). Allowed Logout URLs must include the returnTo origin.

## Checklist

- `.well-known/openid-configuration` is the single source of endpoints.
- Session backend is configured (default DB sessions are fine to start).
- Logout clears the Django session AND hits /v2/logout or the Auth0 session survives.