From 610c9eb1524b47a206d9b17f38b139c20702b775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 24 Jun 2026 14:26:02 +0200 Subject: [PATCH] fix: update Django documentation - JSONField is now used - POST is needed for login - use modern URL patterns Fixes #454 --- docs/backends/salesforce.rst | 16 +++-- docs/backends/saml.rst | 23 +++--- docs/backends/twilio.rst | 7 +- docs/backends/untappd.rst | 8 ++- docs/backends/vk.rst | 7 +- docs/configuration/django.rst | 93 +++++++++++-------------- docs/configuration/porting_from_dsa.rst | 13 ++-- docs/configuration/settings.rst | 7 +- docs/developer_intro.rst | 17 +++-- docs/use_cases.rst | 67 ++++++++++++------ 10 files changed, 149 insertions(+), 109 deletions(-) diff --git a/docs/backends/salesforce.rst b/docs/backends/salesforce.rst index b1113919..e0a211c7 100644 --- a/docs/backends/salesforce.rst +++ b/docs/backends/salesforce.rst @@ -35,8 +35,12 @@ Salesforce uses OAuth v2 for Authentication, check the `official docs`_. ... ) -- Then you can start using ``{% url social:begin 'salesforce-oauth2' %}`` in - your templates +- Then you can start authentication from your templates with a POST form:: + +
+ {% csrf_token %} + +
If using the sandbox mode: @@ -54,8 +58,12 @@ If using the sandbox mode: ... ) -- Then you can start using ``{% url social:begin 'salesforce-oauth2-sandbox' %}`` - in your templates +- Then you can start authentication from your templates with a POST form:: + +
+ {% csrf_token %} + +
.. _official docs: https://www.salesforce.com/us/developer/docs/api_rest/Content/intro_understanding_web_server_oauth_flow.htm .. _Defining Connected Apps: https://www.salesforce.com/us/developer/docs/api_rest/Content/intro_defining_remote_access_applications.htm diff --git a/docs/backends/saml.rst b/docs/backends/saml.rst index 1edc21c8..737f73d4 100644 --- a/docs/backends/saml.rst +++ b/docs/backends/saml.rst @@ -193,22 +193,19 @@ Basic Usage must install and configure your metadata on their system before it will work. - Now everything is set! To allow users to login with any given IdP, you need to - give them a link to the python-social-auth "begin"/"auth" URL and include an - ``idp`` query parameter that specifies the name of the IdP to use. This is - needed since the backend supports multiple IdPs. The names of the IdPs are the - keys used in the ``SOCIAL_AUTH_SAML_ENABLED_IDPS`` setting. + submit the python-social-auth "begin"/"auth" URL and include an ``idp`` + parameter that specifies the name of the IdP to use. This is needed since the + backend supports multiple IdPs. The names of the IdPs are the keys used in the + ``SOCIAL_AUTH_SAML_ENABLED_IDPS`` setting. Django example:: - # In view: - context['testshib_url'] = u"{base}?{params}".format( - base=reverse('social:begin', kwargs={'backend': 'saml'}), - params=urllib.urlencode({'next': '/home', 'idp': 'testshib'}) - ) - # In template: - TestShib Login - # Result: - TestShib Login +
+ {% csrf_token %} + + + +
- Testing with the TestShib_ provider is recommended, as it is known to work well. diff --git a/docs/backends/twilio.rst b/docs/backends/twilio.rst index 9e9853ed..062ce9fe 100644 --- a/docs/backends/twilio.rst +++ b/docs/backends/twilio.rst @@ -29,9 +29,12 @@ setting. 'social_core.backends.twilio.TwilioAuth', -- Usage example:: +- Usage example for Django templates:: - Enter using Twilio +
+ {% csrf_token %} + +
.. _Twilio Connect API: https://www.twilio.com/user/account/connect/apps diff --git a/docs/backends/untappd.rst b/docs/backends/untappd.rst index cd7d5496..c73f033e 100644 --- a/docs/backends/untappd.rst +++ b/docs/backends/untappd.rst @@ -41,8 +41,12 @@ Untappd uses OAuth v2 for Authentication, check the `official docs`_. ... ) -- Then you can start using ``{% url social:begin 'untappd' %}`` in - your templates +- Then you can start authentication from your templates with a POST form:: + +
+ {% csrf_token %} + +
.. _official docs: https://untappd.com/api/docs .. _Add App: https://untappd.com/api/register?register=new diff --git a/docs/backends/vk.rst b/docs/backends/vk.rst index 8bae8dc3..b66ebe6a 100644 --- a/docs/backends/vk.rst +++ b/docs/backends/vk.rst @@ -36,7 +36,12 @@ VK.com uses OAuth2 for Authentication. - Add ``'social_core.backends.vk.VKOAuth2'`` into your ``SOCIAL_AUTH_AUTHENTICATION_BACKENDS``. -- Then you can start using ``/login/vk-oauth2`` in your link href. +- Then you can start authentication from your templates with a POST form:: + +
+ {% csrf_token %} + +
- Also it's possible to define extra permissions with:: diff --git a/docs/configuration/django.rst b/docs/configuration/django.rst index 621761fd..7b822172 100644 --- a/docs/configuration/django.rst +++ b/docs/configuration/django.rst @@ -17,11 +17,15 @@ And for MongoEngine_ ORM:: $ pip install social-auth-app-django-mongoengine +Current ``social-auth-app-django`` releases follow supported Django versions +and require Django 5.2 or newer and Python 3.10 or newer. + Quickstart ---------- -This quickstart covers the essential configuration to get social authentication working in your Django project. +This quickstart covers the essential configuration to get social authentication +working in your Django project. **1. Add to INSTALLED_APPS**:: @@ -49,7 +53,9 @@ This is where you configure your ``client_id``, ``client_secret``, and ``scope`` 'https://www.googleapis.com/auth/userinfo.profile', ] -For other providers, the pattern is ``SOCIAL_AUTH__KEY``, ``SOCIAL_AUTH__SECRET``, and ``SOCIAL_AUTH__SCOPE``. See :doc:`/backends/index` for provider-specific settings. +For other providers, the pattern is ``SOCIAL_AUTH__KEY``, +``SOCIAL_AUTH__SECRET``, and ``SOCIAL_AUTH__SCOPE``. See +:doc:`/backends/index` for provider-specific settings. .. warning:: Never commit credentials to version control. Use environment variables instead:: @@ -75,12 +81,17 @@ For other providers, the pattern is ``SOCIAL_AUTH__KEY``, ``SOCIAL_AUT python manage.py migrate -**7. Add login link in template**:: +**7. Add login form in template**:: - Login with Google +
+ {% csrf_token %} + +
.. note:: - **Database considerations**: SQLite has field length limitations that can cause issues. For production, use PostgreSQL or MySQL. If using MySQL InnoDB or SQLite, add:: + **Database considerations**: SQLite has field length limitations that can + cause issues. For production, use PostgreSQL or MySQL. If using MySQL InnoDB + or SQLite, add:: SOCIAL_AUTH_UID_LENGTH = 223 @@ -117,13 +128,11 @@ Also ensure to define the MongoEngine_ storage setting:: Database -------- -When using PostgreSQL, it's recommended to use the built-in `JSONB` -field to store the extracted ``extra_data``. To enable it define the setting:: - - SOCIAL_AUTH_JSONFIELD_ENABLED = True +The built-in models use Django's native ``JSONField`` to store extracted +``extra_data``. -(For Django 1.7 and higher) you need to sync the database to create needed -models once you added ``social_django`` to your installed apps:: +Sync the database to create needed models once you added ``social_django`` to +your installed apps:: ./manage.py migrate @@ -148,7 +157,8 @@ or Django won't pick them when trying to authenticate the user. Don't miss ``django.contrib.auth.backends.ModelBackend`` if using ``django.contrib.auth`` application or users won't be able to login by username / password method. -For more documentation about setting backends to specific social applications, please see the :doc:`/backends/index`. +For more documentation about setting backends to specific social applications, +please see the :doc:`/backends/index`. .. _django-urls: @@ -157,11 +167,11 @@ URLs entries Add URLs entries:: - urlpatterns = patterns('', + urlpatterns = [ ... path("", include('social_django.urls', namespace="social")), ... - ) + ] In case you need a custom namespace, this setting is also needed:: @@ -175,12 +185,11 @@ In case you need a custom namespace, this setting is also needed:: SOCIAL_AUTH_URL_NAMESPACE = 'accounts:social' -Requiring POST only login -------------------------- - -By default login url ``social:begin`` uses ``GET`` request if you would like to require ``POST`` only (for example to comply with SOC audits) logging in then please use:: +Starting Login +-------------- - SOCIAL_AUTH_REQUIRE_POST = True +The ``social:begin`` view requires a ``POST`` request. Use a form and include +the CSRF token in templates that start authentication. Templates @@ -188,7 +197,10 @@ Templates Example of google-oauth2 backend usage in template:: - Google +
+ {% csrf_token %} + +
Template Context Processors @@ -318,39 +330,17 @@ kwargs to the query set filter method. -JSON field support +JSON field storage ------------------ -Django 3.1 introduces `JSONField` support for all backends and adds a -deprecation warning. - -These are the related settings to enabling this integration: - -- `SOCIAL_AUTH_JSONFIELD_ENABLED` (boolean) - - Same behavior, setting name updated to match `JSONField` being supported by - all systems:: - - SOCIAL_AUTH_POSTGRES_JSONFIELD = True # Before - SOCIAL_AUTH_JSONFIELD_ENABLED = True # After - -- `SOCIAL_AUTH_JSONFIELD_CUSTOM` (import path) - Allows specifying an import string. This gives better control to setting a - custom JSONField. - - For django systems < 3.1 (technically <4), you can set the old `JSONField` - to maintain behavior with earlier social-app-django releases:: - - SOCIAL_AUTH_JSONFIELD_CUSTOM = 'django.contrib.postgres.fields.JSONField' - - For sites running or upgrading to django 3.1+, then can set this so the new - value:: - - SOCIAL_AUTH_JSONFIELD_CUSTOM = 'django.db.models.JSONField' +The current Django models use Django's native ``models.JSONField`` for +``extra_data`` and partial pipeline data. No JSON field setting is needed for +new installations. -- Deprecating setting: `SOCIAL_AUTH_POSTGRES_JSONFIELD` (bool) - Rename this to `SOCIAL_AUTH_JSONFIELD_ENABLED`. The setting will be deprecated - in a future release. +Older migrations still import ``social_django.fields.JSONField`` for migration +compatibility. The historical ``SOCIAL_AUTH_JSONFIELD_ENABLED``, +``SOCIAL_AUTH_JSONFIELD_CUSTOM``, and ``SOCIAL_AUTH_POSTGRES_JSONFIELD`` +settings are only relevant while running those legacy migrations. Exceptions Middleware @@ -367,7 +357,8 @@ Any method can be overridden, but for simplicity these two are recommended:: get_redirect_uri(request, exception) By default, the message is the exception message and the URL for the redirect -is the location specified by the ``LOGIN_ERROR_URL`` setting. +is the location specified by the ``LOGIN_ERROR_URL`` setting. The middleware +supports both synchronous and asynchronous Django request handlers. If a valid backend was detected by ``strategy()`` decorator, it will be available at ``request.strategy.backend`` and ``process_exception()`` will diff --git a/docs/configuration/porting_from_dsa.rst b/docs/configuration/porting_from_dsa.rst index 79c1cfc7..034de396 100644 --- a/docs/configuration/porting_from_dsa.rst +++ b/docs/configuration/porting_from_dsa.rst @@ -41,15 +41,18 @@ URLs The URLs are namespaced, you can chose your namespace, the `example app`_ uses the ``social`` namespace. Replace the old include with:: - urlpatterns = patterns('', + urlpatterns = [ ... - url('', include('social_django.urls', namespace='social')) + path('', include('social_django.urls', namespace='social')), ... - ) + ] -On templates use a namespaced URL:: +On templates use a namespaced URL in a POST form to start login:: - {% url 'social:begin' "google-oauth2" %} +
+ {% csrf_token %} + +
Account disconnection URL would be:: diff --git a/docs/configuration/settings.rst b/docs/configuration/settings.rst index 4e6ff73e..24fb39b5 100644 --- a/docs/configuration/settings.rst +++ b/docs/configuration/settings.rst @@ -65,7 +65,7 @@ results and others for error situations. ``SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/logged-in/'`` Used to redirect the user once the auth process ended successfully. The - value of ``?next=/foo`` is used if it was present + value of the ``next`` request parameter is used if it was present ``SOCIAL_AUTH_LOGIN_ERROR_URL = '/login-error/'`` URL where the user will be redirected in case of an error @@ -75,8 +75,9 @@ results and others for error situations. ``SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/new-users-redirect-url/'`` Used to redirect new registered users, will be used in place of - ``SOCIAL_AUTH_LOGIN_REDIRECT_URL`` if defined. Note that ``?next=/foo`` is appended if present, - if you want new users to go to next, you'll need to do it yourself. + ``SOCIAL_AUTH_LOGIN_REDIRECT_URL`` if defined. Note that the ``next`` + request parameter is appended if present, if you want new users to go to + next, you'll need to do it yourself. ``SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/new-association-redirect-url/'`` Like ``SOCIAL_AUTH_NEW_USER_REDIRECT_URL`` but for new associated accounts diff --git a/docs/developer_intro.rst b/docs/developer_intro.rst index e6ffdd18..321ed3b4 100644 --- a/docs/developer_intro.rst +++ b/docs/developer_intro.rst @@ -15,9 +15,12 @@ When you add the PSA entry to your ``urls.py``, it looks like this:: that "namespace" part on the end is what keeps the names in the PSA-world from colliding with the names in your app, or other 3rd-party apps. So your login -link will look like this:: +form will look like this:: - Login +
+ {% csrf_token %} + +
(See how "social" in the URL mapping matches the value of "namespace" in the ``urls.py`` entry?) @@ -63,11 +66,11 @@ like:: http://example.com/login/github -And clicking on that link will cause the "pipeline" to be started. The pipeline -is a list of functions that build up data about the user as we go through the -steps of the authentication process. (If you really want to understand the -pipeline, look at the source in ``social/backends/base.py``, and see the -``run_pipeline()`` function in ``BaseAuth``.) +Submitting the login form to that URL will cause the "pipeline" to be started. +The pipeline is a list of functions that build up data about the user as we go +through the steps of the authentication process. (If you really want to +understand the pipeline, look at the source in ``social/backends/base.py``, and +see the ``run_pipeline()`` function in ``BaseAuth``.) The design contract for each function in the pipeline is: diff --git a/docs/use_cases.rst b/docs/use_cases.rst index 8e7fe881..e1757949 100644 --- a/docs/use_cases.rst +++ b/docs/use_cases.rst @@ -8,22 +8,26 @@ Return the user to the original page ------------------------------------ There's a common scenario to return the user back to the original page from -where they requested to login. For that purpose, the usual ``next`` query-string -argument is used. The value of this parameter will be stored in the session and -later used to redirect the user when login was successful. +where they requested to login. For that purpose, the usual ``next`` argument is +used. The value of this parameter will be stored in the session and later used +to redirect the user when login was successful. -In order to use it, just define it with your link. For instance, when using -Django:: +In order to use it, just define it with your login request. For instance, when +using Django:: - Login with Facebook +
+ {% csrf_token %} + + +
Pass custom GET/POST parameters and retrieve them on authentication ------------------------------------------------------------------- -In some cases, you might need to send data over the URL, and retrieve it while -processing the after-effect. For example, for conditionally executing code in -custom pipelines. +In some cases, you might need to send data with the login request, and retrieve +it while processing the after-effect. For example, for conditionally executing +code in custom pipelines. In such cases, add it to ``SOCIAL_AUTH_FIELDS_STORED_IN_SESSION``. @@ -31,9 +35,13 @@ In your settings:: SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = ['key'] -In template:: +In a Django template:: - Login with Facebook +
+ {% csrf_token %} + + +
In your custom pipeline, retrieve it using:: @@ -97,8 +105,9 @@ implemented easily):: # access_token parameter like ?access_token=. The URL entry must # contain the backend, like this: # - # url(r'^register-by-token/(?P[^/]+)/$', - # 'register_by_access_token') + # path('register-by-token//', + # register_by_access_token, + # name='register_by_access_token') @psa('social:complete') def register_by_access_token(request, backend): @@ -195,10 +204,16 @@ accomplish that behavior. There are two ways to do it. SOCIAL_AUTH_FACEBOOK_CUSTOM_SECRET = '...' SOCIAL_AUTH_FACEBOOK_CUSTOM_SCOPE = [...] - When the extra permissions are needed, just redirect the user to - ``/login/facebook-custom`` and then get the social auth entry for this new - backend with ``user.social_auth.get(provider='facebook-custom')`` and use - the ``access_token`` in it. + When the extra permissions are needed, start authentication with the new + backend and then get the social auth entry for it with + ``user.social_auth.get(provider='facebook-custom')`` and use the + ``access_token`` in it. In Django templates, start the flow with a POST + form:: + +
+ {% csrf_token %} + +
Enable a user to choose a username from their World of Warcraft characters @@ -263,15 +278,25 @@ to do so, set this setting:: 'approval_prompt': 'auto' } -Then link the users to ``/login/google-oauth2?approval_prompt=force``. If you -want to refresh the ``refresh_token`` only on those users that don't have it, -do it with a pipeline function:: +Then show users a form that starts Google OAuth2 with +``approval_prompt=force``. In Django templates, submit the value in the POST +body:: + +
+ {% csrf_token %} + + +
+ +If you want to refresh the ``refresh_token`` only on those users that don't +have it, redirect them to a page that renders the form above with a pipeline +function:: def redirect_if_no_refresh_token(backend, response, social, *args, **kwargs): if backend.name == 'google-oauth2' and social and \ response.get('refresh_token') is None and \ social.extra_data.get('refresh_token') is None: - return redirect('/login/google-oauth2?approval_prompt=force') + return redirect('/refresh-google-access/') Set this pipeline after ``social_user``::