Token Auth¶
Introduction¶
Token auth is a simple approach to authentication, which is most suitable for mobile apps and embedded systems.
Each user / client has a token generated for them. The token is just a random string - no information is embedded within it, as is the case with JWT.
When a client makes a request, the token needs to be added as a header. The
user object associated with this token is then retrieved from a
TokenAuthProvider
. By default, this is a Piccolo table, but you can
implement your own token provider if you so choose.
The token doesn’t expire. It’s suitable for mobile apps and other systems where tokens can be securely stored on the device. The client logic is simple to implement, as you don’t have to worry about refreshing your token.
It’s not recommended to use this type of authentication with web apps, because you can’t securely store the token using JavaScript, which makes it susceptible to exposure using a XSS attack.
Header format¶
The client has to make a request which includes the Authorization HTTP header, with a value of Bearer SOMETOKEN.
Middleware¶
The middleware builds upon Starlette’s AuthenticationMiddleware
.
TokenAuthBackend
is used to extract the token from the request. If the token
is present and correct, then the request is accepted and the corresponding user
is added to the scope, otherwise it is rejected.
TokenAuthBackend
can work with several different TokenAuthProvider
subclasses. The following are provided by default, but custom ones can be
written by creating your own TokenAuthProvider
subclasses.
SecretTokenAuthProvider¶
This provider checks whether the token provided by the client matches a list of predefined tokens.
from starlette.middleware.authentication import AuthenticationMiddleware
from piccolo_api.token_auth.middleware import (
TokenAuthBackend,
SecretTokenAuthProvider,
)
app = AuthenticationMiddleware(
my_asgi_app,
backend=TokenAuthBackend(SecretTokenAuthProvider(tokens=["abc123"])),
)
If successful a user called secret_token_user is added to the scope.
This provider is useful for protecting internal services, where the client is trusted not to leak the tokens.
It is also useful for protecting login endpoints when accessed from native apps. The client provides the token to be able to access the login endpoint, after which they obtain a unique token, which is used to authenticate with other endpoints.
PiccoloTokenAuthProvider¶
This provider checks a Piccolo database table for a corresponding token, and retrieves a matching user ID. It is the default provider.
from starlette.middleware.authentication import AuthenticationMiddleware
from piccolo_api.token_auth.middleware import (
TokenAuthBackend,
SecretTokenAuthProvider,
)
app = AuthenticationMiddleware(
my_asgi_app,
backend=PiccoloTokenAuthProvider(),
)
You’ll have to run the migrations for this to work correctly.
Endpoints¶
If using Piccolo as a backend, there is an endpoint for logging in, which will return a token.