From 2cbc29c215ce96b8be9aa2f5cc2651dfbe3d66bc Mon Sep 17 00:00:00 2001 From: Raymond Penners Date: Wed, 5 Feb 2025 14:54:52 +0100 Subject: [PATCH] docs(headless): Document Ninja/DRF integration --- ChangeLog.rst | 6 ++ allauth/headless/contrib/ninja/security.py | 10 +++ .../contrib/rest_framework/authentication.py | 5 ++ docs/headless/index.rst | 1 + docs/headless/integrations.rst | 66 +++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 docs/headless/integrations.rst diff --git a/ChangeLog.rst b/ChangeLog.rst index c303726bf3..4d30f77023 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -20,6 +20,12 @@ Note worthy changes - Headless: added a new setting, ``HEADLESS_CLIENTS`` which you can use to limit the types of API clients (app/browser). +- Headless: expanded the React SPA example to showcase integration with + Django Ninja as well as Django REST framework. + +- Headless: added out of the box support for being able to use the headless + session tokens with Django Ninja and Django REST framework. + 65.3.1 (2024-12-25) ******************* diff --git a/allauth/headless/contrib/ninja/security.py b/allauth/headless/contrib/ninja/security.py index 64e1bc2e5d..2bd8917fbb 100644 --- a/allauth/headless/contrib/ninja/security.py +++ b/allauth/headless/contrib/ninja/security.py @@ -10,6 +10,11 @@ class XSessionTokenAuth(AuthBase): + """ + This security class uses the X-Session-Token that django-allauth + is using for authentication purposes. + """ + openapi_type: str = "apiKey" def __call__(self, request: HttpRequest): @@ -21,6 +26,11 @@ def __call__(self, request: HttpRequest): return None def get_session_token(self, request: HttpRequest) -> typing.Optional[str]: + """ + Returns the session token for the given request, by looking up the + ``X-Session-Token`` header. Override this if you want to extract the token + from e.g. the ``Authorization`` header. + """ return request.headers.get("X-Session-Token") diff --git a/allauth/headless/contrib/rest_framework/authentication.py b/allauth/headless/contrib/rest_framework/authentication.py index a6e45023f0..2befb0acff 100644 --- a/allauth/headless/contrib/rest_framework/authentication.py +++ b/allauth/headless/contrib/rest_framework/authentication.py @@ -22,4 +22,9 @@ def authenticate(self, request: HttpRequest): return None def get_session_token(self, request: HttpRequest) -> typing.Optional[str]: + """ + Returns the session token for the given request, by looking up the + ``X-Session-Token`` header. Override this if you want to extract the token + from e.g. the ``Authorization`` header. + """ return request.headers.get("X-Session-Token") diff --git a/docs/headless/index.rst b/docs/headless/index.rst index 422751e274..4d293d9df7 100644 --- a/docs/headless/index.rst +++ b/docs/headless/index.rst @@ -9,4 +9,5 @@ Headless api adapter tokens + integrations faq diff --git a/docs/headless/integrations.rst b/docs/headless/integrations.rst new file mode 100644 index 0000000000..21c602c2ac --- /dev/null +++ b/docs/headless/integrations.rst @@ -0,0 +1,66 @@ +Integrations +============ + +When using allauth headless in non-browser contexts, such as mobile apps, a +session token is used to keep track of the authentication state. This session +token is handed over by the app by providing the ``X-Session-Token`` request +header. + +Once a user authenticates, you can hand out your own type of token by setting up +a specific :doc:`tokens`. However, if you do not have any requirements that +prescribe a specific token strategy, you can also opt to use the same +authentication strategy that allauth is using. In order to do so, integration +with Django Ninja and Django REST framework is offered out of the box. + + +Django Ninja +------------ + +For Django Ninja, the following security class is available: + +.. autoclass:: allauth.headless.contrib.ninja.security.XSessionTokenAuth + :members: + +An example on how to use that security class in your own code is listed below: + +.. code-block:: python + + from allauth.headless.contrib.ninja.security import x_session_token_auth + from ninja import NinjaAPI + + api = NinjaAPI() + + @api.get("/your/own/api", auth=[x_session_token_auth]) + def your_own_api(request): + ... + + + + +Django REST framework +--------------------- + +For Django REST framework, the following authentication class is available: + +.. autoclass:: allauth.headless.contrib.rest_framework.authentication.XSessionTokenAuthentication + :members: + +An example on how to use that authentication class in your own code is listed below: + +.. code-block:: python + + from allauth.headless.contrib.rest_framework.authentication import ( + XSessionTokenAuthentication, + ) + from rest_framework import permissions + from rest_framework.views import APIView + + class YourOwnAPIView(APIView): + + authentication_classes = [ + XSessionTokenAuthentication, + ] + permission_classes = [permissions.IsAuthenticated] + + def get(self, request): + ...