Django Session Auth

Docs: https://docs.djangoproject.com/en/dev/topics/auth

Requiring auth

Note

Current user will always be accessible as self.request.user.

Read more: https://docs.djangoproject.com/en/stable/topics/auth/default/

We provide two classes to require Django session auth in you API:

Example, how to use the auth class and how to get self.request.user:

Note

Using any of these classes would also automatically enable CSRF checks for this view. Because it is not secure to use Django session auth without CSRF checks.

Reusing pre-existing views

We provide several pre-existing views to get Django session cookie. So, users won’t have to write tons of boilerplate code.

We provide two Reusable controllers to obtain Django session cookie:

  1. DjangoSessionSyncController for sync controllers

  2. DjangoSessionAsyncController for async controllers

To use them, you will need to:

  1. Provide actual types for serializer, request model, and response body

  2. Redefine convert_auth_payload() to convert your request model into the kwargs of django.contrib.auth.authenticate() to authenticate your request

  3. Redefine make_api_response() to return the response in the format of your choice

Run result

$ curl http://127.0.0.1:8000/api/auth/ -D - -X POST -d '{"username": "test_user", "password": "password"}' -H 'Content-Type: application/json'
HTTP/1.1 200 OK
date: Sun, 29 Mar 2026 18:52:12 GMT
server: uvicorn
Content-Type: application/json
X-Frame-Options: DENY
Vary: Accept-Language, Cookie
Content-Language: en
Content-Length: 15
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Set-Cookie: csrftoken=bdYMAf61wRYG1Vq2JsTzonA0CGvFWF4k; expires=Sun, 28 Mar 2027 18:52:12 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Set-Cookie: sessionid=8v3m0keehe4lex54vfvqlmehjh32k1h8; expires=Sun, 12 Apr 2026 18:52:12 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax

{"user_id":"1"}

OpenAPI Schema

Preview openapi.json
{
  "components": {
    "schemas": {
      "DjangoSessionPayload": {
        "description": "Payload for default version of a django session request body.\n\nIs also used as kwargs for :func:`django.contrib.auth.authenticate`.",
        "properties": {
          "password": {
            "title": "Password",
            "type": "string"
          },
          "username": {
            "title": "Username",
            "type": "string"
          }
        },
        "required": [
          "username",
          "password"
        ],
        "title": "DjangoSessionPayload",
        "type": "object"
      },
      "DjangoSessionResponse": {
        "description": "Default response type for django session endpoint.",
        "properties": {
          "user_id": {
            "title": "User Id",
            "type": "string"
          }
        },
        "required": [
          "user_id"
        ],
        "title": "DjangoSessionResponse",
        "type": "object"
      },
      "ErrorDetail": {
        "description": "Base schema for error details description.",
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "string"
                }
              ]
            },
            "title": "Loc",
            "type": "array"
          },
          "msg": {
            "title": "Msg",
            "type": "string"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "msg"
        ],
        "title": "ErrorDetail",
        "type": "object"
      },
      "ErrorModel": {
        "description": "Default error response schema.\n\nCan be customized.\nSee :ref:`customizing-error-messages` for more details.",
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "required": [
          "detail"
        ],
        "title": "ErrorModel",
        "type": "object"
      }
    },
    "securitySchemes": {}
  },
  "info": {
    "title": "Django Modern Rest",
    "version": "0.1.0"
  },
  "openapi": "3.2.0",
  "paths": {
    "/api/sessionsynccontroller/": {
      "post": {
        "deprecated": false,
        "operationId": "postSessionsynccontrollerApiSessionsynccontroller",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DjangoSessionPayload"
              }
            }
          },
          "description": "Payload for default version of a django session request body.\n\nIs also used as kwargs for :func:`django.contrib.auth.authenticate`.",
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DjangoSessionResponse"
                }
              }
            },
            "description": "OK",
            "headers": {
              "Set-Cookie: sessionid": {
                "required": true,
                "schema": {
                  "example": "sessionid=123",
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Raised when request components cannot be parsed"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Unauthorized"
          },
          "406": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Raised when provided `Accept` header cannot be satisfied"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Raised when returned response does not match the response schema"
          }
        },
        "summary": "By default cookies are acquired on post."
      }
    }
  }
}

Any further customizations are also possible.

API Reference

class dmr.security.django_session.auth.DjangoSessionSyncAuth(security_scheme_name: str = 'django_session', csrf_scheme_name: str = 'csrf')[source]

Reuses Django’s regular session auth for the API.

This class is used for sync endpoints.

__call__(endpoint: Endpoint, controller: Controller[BaseSerializer]) Any | None[source]

Does check for the existing request user.

authenticate(endpoint: Endpoint, controller: Controller[BaseSerializer]) Any | None[source]

Override this method to provide other authentication logic.

For example: checking that user is staff / superuser.

classmethod provide_response_specs(metadata: EndpointMetadata, controller_cls: type[Controller[BaseSerializer]], existing_responses: Mapping[HTTPStatus, ResponseSpec]) list[ResponseSpec]

Provides responses that can happen when user is not authed.

property security_requirement: dict[str, list[str]]

Provides a security schema usage requirement.

property security_schemes: dict[str, SecurityScheme | Reference]

Provides a security schema definition.

class dmr.security.django_session.auth.DjangoSessionAsyncAuth(security_scheme_name: str = 'django_session', csrf_scheme_name: str = 'csrf')[source]

Reuses Django’s regular session auth for the API.

This class is used for async endpoints.

async __call__(endpoint: Endpoint, controller: Controller[BaseSerializer]) Any | None[source]

Does check for the existing request user.

async authenticate(endpoint: Endpoint, controller: Controller[BaseSerializer]) Any | None[source]

Override this method to provide other authentication logic.

For example: checking that user is staff / superuser.

classmethod provide_response_specs(metadata: EndpointMetadata, controller_cls: type[Controller[BaseSerializer]], existing_responses: Mapping[HTTPStatus, ResponseSpec]) list[ResponseSpec]

Provides responses that can happen when user is not authed.

property security_requirement: dict[str, list[str]]

Provides a security schema usage requirement.

property security_schemes: dict[str, SecurityScheme | Reference]

Provides a security schema definition.