# 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

Changed in version v1.0.

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

    @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.

    @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)