Encrypted Token Authentication

Last updated 6 months ago

Introduction

Encrypted Token Authentication is a basic form of authentication but is very helpful in ensuring that unauthorized users do not have access to your API. Adding token authentication to your resources is very simple.

If you don't want to go ahead and setup an entire API system yet then this might be a good option to test your idea first.

Getting Started

We can simply add token authentication to our resources by adding the correct authentication class to our resource:

from entry.api.Resource import Resource
from entry.api.JsonSerialize import JsonSerialize
from entry.api.auth import EncryptedTokenAuthentication
from app.User import User
class UserResource(Resource, JsonSerialize, EncryptedTokenAuthentication):
model = User

That's it. We now can open our API back up and try an API request to our resource. We should see an error of a missing token. Masonite Entry looks for the token inside the token parameter. If we pass an arbitrary value in the token parameter and hit send then we will receive an error saying we have an invalid token.

Routes

We can add all the routes we need by importing the controller and calling the routes method:

from entry.api.controllers import EncryptedGrantController
ROUTES = [
...
EncryptedGrantController.routes(),
...
]

Creating Tokens

This type of token authentication does not require any database connections. It's simply an encrypted token with some information in which is decrypted and checked for expiration.

get
Requesting a Token

http://localhost:8000
/encrypt/token
Generate a token that will expire in 1 day
Request
Response
Query Parameters
scope
optional
string
Any scopes you want the token to have
username
required
string
The username you are authenticating with
password
required
string
The password you are authenticating with
200: OK
If your username and password are successful
{
"token": "gAAAAABbLqAi9fnQ-4X1gPojYmnXtT-zbq7_zn8dgcue03WIINQ8nu9dvIupX6q69omUXQ5aZUYBstQV1KlC7aufPUK7A739u0i6vZBQVDpK_DG_Hne4LE0nGIjCfuE6CLxiQVVyRhyOc05YGQvoETPtZhF3zt07qRWeGml5zVHdM90TwIZBjjJVKMgHE47sz_uLtO7Ni0IIcF1xuNg7iNkgfDVk-Td74w=="
}
401: Unauthorized
If your username or password is incorrect
{
"error": "Username or password do not match"
}

You can now use this token to make any authenticated calls.

CSRF Middleware

Some of these routes are POST routes. Because they are externally facing, they should not be under CSRF protection. If you are using these routes internally then it might be worth it to keep the CSRF protection on and just pass the CSRF token you receive on that page load.

You can turn off CSRF protection on specific routes by adding them to your exempt attribute on your CSRFMiddleware:

class CsrfMiddleware:
exempt = [
'/encrypt/refresh'
]

post
Refreshing a Token

http://localhost:8000
/encrypt/refresh
This endpoint is simply used to create a new authentication token using a previously expired authentication token.
Request
Response
Path Parameters
token
required
string
The token that is presumably expired
200: OK
{
"token": "gAAAAABbLqAi9fnQ-4X1gPojYmnXtT-zbq7_zn8dgcue03WIINQ8nu9dvIupX6q69omUXQ5aZUYBstQV1KlC7aufPUK7A739u0i6vZBQVDpK_DG_Hne4LE0nGIjCfuE6CLxiQVVyRhyOc05YGQvoETPtZhF3zt07qRWeGml5zVHdM90TwIZBjjJVKMgHE47sz_uLtO7Ni0IIcF1xuNg7iNkgfDVk-Td74w=="
}

Once a token has expired, it is no longer valid and cannot make any endpoint calls. With this authentication method, you can use an old token you have been given in order to generate a new one using the endpoint above.