File: resource-server.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 (88 lines) | stat: -rw-r--r-- 2,767 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
Resource Server
===============

Protect users resources, so that only the authorized clients with the
authorized access token can access the given scope resources.

A resource server can be a different server other than the authorization
server. Here is the way to protect your users' resources in Django::

    from authlib.integrations.django_oauth2 import ResourceProtector, BearerTokenValidator
    from django.http import JsonResponse

    require_oauth = ResourceProtector()
    require_oauth.register_token_validator(BearerTokenValidator(OAuth2Token))

    @require_oauth('profile')
    def user_profile(request):
        user = request.oauth_token.user
        return JsonResponse(dict(sub=user.pk, username=user.username))

If the resource is not protected by a scope, use ``None``::

    @require_oauth()
    def user_profile(request):
        user = request.oauth_token.user
        return JsonResponse(dict(sub=user.pk, username=user.username))

    # or with None

    @require_oauth(None)
    def user_profile(request):
        user = request.oauth_token.user
        return JsonResponse(dict(sub=user.pk, username=user.username))

The decorator ``require_oauth`` will add an ``oauth_token`` property on ``request``,
which is the instance of current in-use Token.

Multiple Scopes
---------------

.. versionchanged:: v1.0

You can apply multiple scopes to one endpoint in **AND**, **OR** and mix modes.
Here are some examples:

.. code-block:: python

    @require_oauth(['profile email'])
    def user_profile(request):
        user = request.oauth_token.user
        return JsonResponse(dict(sub=user.pk, username=user.username))

It requires the token containing both ``profile`` and ``email`` scope.

.. code-block:: python

    @require_oauth(['profile', 'email'])
    def user_profile(request):
        user = request.oauth_token.user
        return JsonResponse(dict(sub=user.pk, username=user.username))

It requires the token containing either ``profile`` or ``email`` scope.


It is also possible to mix **AND** and **OR** logic. e.g.::

    @app.route('/profile')
    @require_oauth(['profile email', 'user'])
    def user_profile(request):
        user = request.oauth_token.user
        return JsonResponse(dict(sub=user.pk, username=user.username))

This means if the token will be valid if:

1. token contains both ``profile`` and ``email`` scope
2. or token contains ``user`` scope

Optional ``require_oauth``
--------------------------

There is one more parameter for ``require_oauth`` which is used to serve
public endpoints::

    @require_oauth(optional=True)
    def timeline_api(request):
        if request.oauth_token:
            return get_user_timeline(request.oauth_token.user)
        return get_public_timeline(request)