File: django.rst

package info (click to toggle)
python-authlib 1.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,016 kB
  • sloc: python: 26,998; makefile: 53; sh: 14
file content (144 lines) | stat: -rw-r--r-- 4,787 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
.. _django_client:

Django OAuth Client
===================

.. meta::
    :description: The built-in Django integrations for OAuth 1.0 and
        OAuth 2.0 clients, powered by Authlib.

.. module:: authlib.integrations.django_client
    :noindex:

Looking for OAuth providers?

- :ref:`django_oauth1_server`
- :ref:`django_oauth2_server`

The Django client can handle OAuth 1 and OAuth 2 services. Authlib has
a shared API design among framework integrations. Get started with
:ref:`frameworks_clients`.

Create a registry with :class:`OAuth` object::

    from authlib.integrations.django_client import OAuth

    oauth = OAuth()

The common use case for OAuth is authentication, e.g. let your users log in
with Twitter, GitHub, Google etc.

.. important::

    Please read :ref:`frameworks_clients` at first. Authlib has a shared API
    design among framework integrations, learn them from :ref:`frameworks_clients`.


Configuration
-------------

Authlib Django OAuth registry can load the configuration from your Django
application settings automatically. Every key value pair can be omitted.
They can be configured from your Django settings::

    AUTHLIB_OAUTH_CLIENTS = {
        'twitter': {
            'client_id': 'Twitter Consumer Key',
            'client_secret': 'Twitter Consumer Secret',
            'request_token_url': 'https://api.twitter.com/oauth/request_token',
            'request_token_params': None,
            'access_token_url': 'https://api.twitter.com/oauth/access_token',
            'access_token_params': None,
            'refresh_token_url': None,
            'authorize_url': 'https://api.twitter.com/oauth/authenticate',
            'api_base_url': 'https://api.twitter.com/1.1/',
            'client_kwargs': None
        }
    }

There are differences between OAuth 1.0 and OAuth 2.0, please check the parameters
in ``.register`` in :ref:`frameworks_clients`.

Saving Temporary Credential
---------------------------

In OAuth 1.0, we need to use a temporary credential to exchange access token,
this temporary credential was created before redirecting to the provider (Twitter),
we need to save this temporary credential somewhere in order to use it later.

In OAuth 1, Django client will save the request token in sessions. In this
case, you just need to configure Session Middleware in Django::

    MIDDLEWARE = [
        'django.contrib.sessions.middleware.SessionMiddleware'
    ]

Follow the official Django documentation to set a proper session. Either a
database backend or a cache backend would work well.

.. warning::

    Be aware, using secure cookie as session backend will expose your request
    token.

Routes for Authorization
------------------------

Just like the example in :ref:`frameworks_clients`, everything is the same.
But there is a hint to create ``redirect_uri`` with ``request`` in Django::

    def login(request):
        # build a full authorize callback uri
        redirect_uri = request.build_absolute_uri('/authorize')
        return oauth.twitter.authorize_redirect(request, redirect_uri)


Auto Update Token via Signal
----------------------------

Instead of defining an ``update_token`` method and passing it into OAuth registry,
it is also possible to use signals to listen for token updates::

    from django.dispatch import receiver
    from authlib.integrations.django_client import token_update

    @receiver(token_update)
    def on_token_update(sender, name, token, refresh_token=None, access_token=None, **kwargs):
        if refresh_token:
            item = OAuth2Token.find(name=name, refresh_token=refresh_token)
        elif access_token:
            item = OAuth2Token.find(name=name, access_token=access_token)
        else:
            return

        # update old token
        item.access_token = token['access_token']
        item.refresh_token = token.get('refresh_token')
        item.expires_at = token['expires_at']
        item.save()


Django OpenID Connect Client
----------------------------

An OpenID Connect client is no different than a normal OAuth 2.0 client. When
registered with the ``openid`` scope, the built-in Django OAuth client will handle
everything automatically::

    oauth.register(
        'google',
        ...
        server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
        client_kwargs={'scope': 'openid profile email'}
    )

When we get the returned token::

    token = oauth.google.authorize_access_token(request)

There should be a ``id_token`` in the response. Authlib has called `.parse_id_token`
automatically, we can get ``userinfo`` in the ``token``::

    userinfo = token['userinfo']

Find Django Google login example at https://github.com/authlib/demo-oauth-client/tree/master/django-google-login