Django Rest Framework JWT: How to change the token expiration time when logged in
JWT token refresh is a little confusing, and i hope this explanation helps.
- tokens have an
issued at
time (iat
in the token) - tokens have an
expiration date
(now() + 1 hour, for example) - the token can't be changed. server can only issue a new one
iat
never changes, butexpires
does change with each refresh
When you want to extend a token, this is what happens:
- You send your
token
to the server endpoint/.../refresh/
- Server checks its not expired:
now() <= token.iat + JWT_REFRESH_EXPIRATION_DELTA
- If not expired:
- Issue a NEW token (returned in the json body, same as login)
- New Token is valid for
now() + JWT_EXPIRATION_DELTA
- The
issued at
value in the token does not change - App now has 2 tokens (technically).
- App discards the old token and starts sending the new one
- If expired: return error message and 400 status
Example
You have EXPIRATION=1 hour
, and a REFRESH_DELTA=2 days
. When you login you get a token that says "created-at: Jun-02-6pm". You can refresh this token (or any created from it by refreshing) for 2 days. This means, for this login, the longest you can use a token without re-logging-in, is 2 days and 1 hour. You could refresh it every 1 second, but after 2 days exactly the server would stop allowing the refresh, leaving you with a final token valid for 1 hour. (head hurts).
Settings
You have to enable this feature in the backend in the JWT_AUTH
settings in your django settings file. I believe that it is off by default. Here are the settings I use:
JWT_AUTH = {
# how long the original token is valid for
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=2),
# allow refreshing of tokens
'JWT_ALLOW_REFRESH': True,
# this is the maximum time AFTER the token was issued that
# it can be refreshed. exprired tokens can't be refreshed.
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
Then you can call the JWT refresh view, passing in your token in the body (as json) and getting back a new token. Details are in the docs at http://getblimp.github.io/django-rest-framework-jwt/#refresh-token
$ http post localhost:8000/auth/jwt/refresh/ --json token=$TOKEN
Which returns:
HTTP 200
{
"token": "new jwt token value"
}