API Authentication
The Vanilo REST API can only be accessed after authentication.
The authentication subsystem is an implementation of the Bearer Token specification which is a subset of the OAuth 2.0 standard.
Authorization Workflow
- Authenticate the user: Receive tokens.
- Call your API: Use the retrieved Access Token to call your API.
- Refresh Tokens: Use a Refresh Token to request new tokens when the existing ones expire.
Authentication
To begin the flow, you need to have a user of type API and their username and password.
The users of the REST API are stored in the same list of users where the "admin" users are.
The consumers of the REST API are not human but applications, thus only
users of type api
are allowed to authenticate against the REST API.
Login
Use the /api/1.0/auth/login
endpoint to authenticate the user and receive tokens.
You need to pass the following parameters to the login endpoint:
client_id
- The email address of the API userclient_secret
- The password of the API user
The request data must be POST
and sent with application/x-www-form-urlencoded
encoding.
If all goes well, you'll receive an HTTP 200 response with a payload containing access_token
,
refresh_token
, expires_in
, and token_type
values:
{
"access_token": "eyJhbGciOiJIVCJ9.eyJixjM0NTY3ODkwIioNSiW0jxTyT5TyCjIxOTI3MjJ9.kOkTVr4rPq5wiv2WgbBqUQ",
"token_type": "Bearer",
"expires_in": 9000,
"refresh_token": "eyJhbR5cCI6IkXV9.ezdWIiOzNSwiaWF0IjoxNTYyMTg5MOjE1NjU5MsdDMsw.lFlaJqxPP4xX-c3wWACjvO"
}
The returned access token can be used for calling the API.
Calling The API
The access and refresh tokens are JWT encoded credentials.
To use the token to call the api you have to pass it as the Authorization
HTTP header in your
request:
Authorization: Bearer eyJhbGciOiJIVCJ9.eyJixjM0NTY3ODkwIioNSiW0jxTyT5TyCjIxOTI3MjJ9.kOkTVr4rPq5wiv2WgbBqUQ
Refreshing Tokens
Access tokens have a limited lifetime, specified in seconds in the expires_in
field of the login
response.
When the Access Token expires you'll receive an HTTP 401 response with the message:
{
"message": "Expired token. Use the refresh token to get a new one"
}
Using the Refresh Token, you can get a new access token. Make a POST request to the
/1.0/auth/token
endpoint with the following parameter:
refresh_token
- The refresh token you've received in the initial login request.
The request data must be sent with application/x-www-form-urlencoded
encoding.
If all goes well, you'll receive an HTTP 200 response with the same content as at login:
{
"access_token": "eyJhbGciOiJIVCJ9.eyJixjM0NTY3ODkwIioNSiW0jxTyT5TyCjIxOTI3MjJ9.kOkTVr4rPq5wiv2WgbBqUQ",
"token_type": "Bearer",
"expires_in": 9000,
"refresh_token": "eyJhbR5cCI6IkXV9.ezdWIiOzNSwiaWF0IjoxNTYyMTg5MOjE1NjU5MsdDMsw.lFlaJqxPP4xX-c3wWACjvO"
}
It's bad practice calling the endpoint to get a new Access Token every time you call an API. Auth endpoints are rate limited that will restrict the amount of requests allowed.
Refresh tokens must be stored securely since they allow a user to remain authenticated for a very long period (1 year unless differently configured).
Refresh tokens have an extended lifecycle, 1 year by default. Once a refresh token expires you'll get an HTTP 401 response when invoking the token endpoint. In this case you need to invoke the login endpoint again to obtain a new access and refresh token.
Configuration
The lifetime of tokens (in seconds) can be configured.
Access Token Lifetime
Configuration entry api.auth.access_token.ttl
: defaults to 90000 (sec),
ie. 25 hours. To use a custom value, set a different value in
config/api.json
:
{
"auth": {
"access_token": {
"ttl": 604800
}
}
}
Refresh Token Lifetime
Configuration entry api.auth.refresh_token.ttl
: defaults to 31708800 (sec),
ie. 367 days. To use a custom value, set a different value in
config/api.json
:
{
"auth": {
"refresh_token": {
"ttl": 63417600
}
}
}
JWT Token Signature
The tokens are being cryptographically signed and verified.
The signing key is being read from the api.auth.token_signature
configuration. It has a default setting that can be changed in the
config/api.json
file:
To use a custom signing key, set some long, random sequence of
characters that only the server knows.
! Changing the API signing key will invalidate every existing API token.
config/api.json
:
{
"auth": {
"token_signature": "D!3@a83cMtLKzI=B19bKlJWLvJCyf/FUg|5H3e+CjE0cvIAXlcjdsCOjknQgrk"
}
}