This is the documentation of the development version, check the Stable Version documentation.

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

You can apply multiple scopes to one endpoint in AND and OR modes. The default is AND mode.

@require_oauth('profile email', 'AND')
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.

@require_oauth('profile email', 'OR')
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 pass a function as the scope operator. e.g.:

def scope_operator(token_scopes, resource_scopes):
    # this equals "AND"
    return token_scopes.issuperset(resource_scopes)

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

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)