# Authorization Server

The Authorization Server provides several endpoints for temporary credentials, authorization, and issuing token credentials. When the resource owner (user) grants the authorization, this server will issue a token credential to the client.

Currently, Authlib Django implementation is using cache a lot, which means you don’t have to handle temporary credentials, timestamp and nonce yourself, they are all built-in.

To create an authorization server, only Client and Token models are required:

    from your_project.models import Client, Token
    from authlib.integrations.django_oauth1 import CacheAuthorizationServer

    authorization_server = CacheAuthorizationServer(Client, Token)

## Resource Owner

Resource Owner is the user who is using your service. A resource owner can log in your website with username/email and password, or other methods. In Django, we can use the built in contrib user:

    from django.contrib.auth.models import User

## Client

A client is an application making protected resource requests on behalf of the resource owner and with its authorization. It contains at least three information:

- Client Identifier, usually called client_id

- Client Password, usually called client_secret

- Client RSA Public Key (if RSA-SHA1 signature method supported)

Authlib has no implementation for client model in Django. You need to implement it yourself:

    from django.db import models
    from django.contrib.auth.models import User
    from authlib.oauth1 import ClientMixin

    class Client(models.Model, ClientMixin):
        user = models.ForeignKey(User, on_delete=CASCADE)
        client_id = models.CharField(max_length=48, unique=True, db_index=True)
        client_secret = models.CharField(max_length=48, blank=True)
        default_redirect_uri = models.TextField(blank=False, default='')

        def get_default_redirect_uri(self):
            return self.default_redirect_uri

        def get_client_secret(self):
            return self.client_secret

        def get_rsa_public_key(self):
            return None

A client is registered by a user (developer) on your website. Get a deep inside with `ClientMixin` API reference.

## Token

A token credential is used to access resource owners’ resources. Unlike OAuth 2, the token credential will not expire in OAuth 1. This token credentials are supposed to be saved into a persist database rather than a cache.

Here is an example of how it looks in Django:

    from django.db import models
    from django.contrib.auth.models import User
    from authlib.oauth1 import TokenCredentialMixin

    class Token(models.Model, TokenCredentialMixin):
        user = models.ForeignKey(User, on_delete=CASCADE)
        client_id = models.CharField(max_length=48, db_index=True)
        oauth_token = models.CharField(max_length=84, unique=True, db_index=True)
        oauth_token_secret = models.CharField(max_length=84)

        def get_oauth_token(self):
            return self.oauth_token

        def get_oauth_token_secret(self):
            return self.oauth_token_secret

## Server Implementation

It is ready to create the endpoints for authorization and issuing tokens. Let’s start with the temporary credentials endpoint, which is used for clients to fetch a temporary credential:

    from django.views.decorators.http import require_http_methods

    @require_http_methods(["POST"])
    def initiate_temporary_credential(request):
        return server.create_temporary_credential_response(request)

The endpoint for resource owner authorization. OAuth 1 Client will redirect user to this authorization page, so that resource owner can grant or deny this request:

    from django.shortcuts import render

    def authorize(request):
        # make sure that user is logged in for yourself
        if request.method == 'GET':
            try:
                req = server.check_authorization_request(request)
                context = {'req': req}
                return render(request, 'authorize.html', context)
            except OAuth1Error as error:
                context = {'error': error}
                return render(request, 'error.html', context)

        granted = request.POST.get('granted')
        if granted:
            grant_user = request.user
        else:
            grant_user = None

        try:
            return server.create_authorization_response(request, grant_user)
        except OAuth1Error as error:
            context = {'error': error}
            return render(request, 'error.html', context)

Then the final token endpoint. OAuth 1 Client will use the given temporary credential and the `oauth_verifier` authorized by resource owner to exchange the token credential:

    from django.views.decorators.http import require_http_methods

    @require_http_methods(["POST"])
    def issue_token(request):
        return server.create_token_response(request)

At last, you need to register these views into url patterns.