This package supports two refresh methods:
- Single token refresh (by default)
- Long running refresh tokens
GRAPHQL_JWT = { "JWT_VERIFY_EXPIRATION": True, "JWT_EXPIRATION_DELTA": timedelta(minutes=5), "JWT_REFRESH_EXPIRATION_DELTA": timedelta(days=7), }
It means that you need to refresh every 5 mins (payload.exp
) and even you keep on refreshing token every 5 mins, you will still be logout in 7 days after the first token has been issued (refreshExpiresIn
).
refreshToken
to obtain a brand new token with renewed expiration time for non-expired tokens:
mutation RefreshToken($token: String!) { refreshToken(token: $token) { token payload refreshExpiresIn } }
Refresh and keeping tokens alive
Refresh after 4 minutes...
- Token issued
exp = orig_iat + JWT_EXPIRATION_DELTA (payload.exp) refreshToken (t): exp = t + JWT_EXPIRATION_DELTA
- Signature expiration (login is required)
when: t = exp exp = refresh_at + JWT_EXPIRATION_DELTA verifyToken (t): error! if JWT_VERIFY_EXPIRATION=true
- Refresh expiration
when: t = orig_iat + JWT_REFRESH_EXPIRATION_DELTA (refreshExpiresIn) refreshToken (t): error!
Refresh tokens stored on database.
Add graphql_jwt.refresh_token
to your INSTALLED_APPS:
INSTALLED_APPS = [ ... "graphql_jwt.refresh_token.apps.RefreshTokenConfig", ... ]
GRAPHQL_JWT = { "JWT_VERIFY_EXPIRATION": True, "JWT_LONG_RUNNING_REFRESH_TOKEN": True, "JWT_EXPIRATION_DELTA": timedelta(minutes=5), "JWT_REFRESH_EXPIRATION_DELTA": timedelta(days=7), }
It means that you need to refresh every 5 mins (payload.exp
) and you need to replace your refresh token in 7 days after it has been issued (refreshExpiresIn
).
Add mutations to the root schema:
import graphene import graphql_jwt class Mutation(graphene.ObjectType): token_auth = graphql_jwt.ObtainJSONWebToken.Field() verify_token = graphql_jwt.Verify.Field() refresh_token = graphql_jwt.Refresh.Field() revoke_token = graphql_jwt.Revoke.Field() schema = graphene.Schema(mutation=Mutation)
tokenAuth
to authenticate the user and obtain a JSON Web Token and Refresh Token:mutation TokenAuth($username: String!, $password: String!) { tokenAuth(username: $username, password: $password) { token payload refreshToken refreshExpiresIn } }
refreshToken
to refresh your token, using therefreshToken
you already got during authorization:mutation RefreshToken($refreshToken: String!) { refreshToken(refreshToken: $refreshToken) { token payload refreshToken refreshExpiresIn } }
revokeToken
to revoke a validrefreshToken
. The invalidation takes place immediately, and therefreshToken
cannot be used again after the revocation:mutation RevokeToken($refreshToken: String!) { revokeToken(refreshToken: $refreshToken) { revoked } }
When a refresh token is requested and jwt_cookie
decorator is set, the response will set the given cookie with the refresh token string.
Configure the JWT_REFRESH_EXPIRED_HANDLER
setting that checks if the refresh token is expired:
GRAPHQL_JWT = { "JWT_VERIFY_EXPIRATION": True, "JWT_LONG_RUNNING_REFRESH_TOKEN": True, "JWT_REFRESH_EXPIRED_HANDLER": lambda orig_iat, context: False, }
Automatically revoke a refresh token after it has been used:
from django.dispatch import receiver from graphql_jwt.refresh_token.signals import refresh_token_rotated @receiver(refresh_token_rotated) def revoke_refresh_token(sender, request, refresh_token, **kwargs): refresh_token.revoke(request)
.. automethod:: graphql_jwt.refresh_token.management.commands.cleartokens.Command.handle
Delete revoked refresh tokens with cleartokens
command.
$ python manage.py cleartokens --help
usage: cleartokens [--expired]
optional arguments:
--expired Clears expired tokens
The --expired
argument allows the user to remove those refresh tokens whose lifetime is greater than the amount specified by JWT_REFRESH_EXPIRATION_DELTA
setting.