djangorestframework-simplejwt icon indicating copy to clipboard operation
djangorestframework-simplejwt copied to clipboard

Sliding Token Clarification

Open IvanFon opened this issue 4 years ago • 25 comments

Hi, I'm trying to use sliding tokens, but I think I need a bit of clarification. From what I understand, when I generate a sliding token, it can be used for authentication until it's expiration claim expires. After the expiration claim expires, I can still refresh the token until the refresh expiration claim expires.

The problem I'm running into is that I can only refresh the token while the auth expiration claim is valid. I'm not sure if this is intended or if I'm doing something wrong, but this makes it seem like there's no point to the refresh expiration claim.

My config is:

SIMPLE_JWT = {
    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.SlidingToken',),
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=1),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

I can obtain a token:

Request:
> POST /api/users/token/ HTTP/1.1
> Host: localhost:8000
> User-Agent: insomnia/6.6.2
> Content-Type: application/json
> Accept: */*
> Content-Length: 44

| {
| 	"username": "test",
| 	"password": "test"
| }

< HTTP/1.1 200 OK
< Date: Thu, 29 Aug 2019 16:56:17 GMT
< Server: WSGIServer/0.2 CPython/3.7.4
< Content-Type: application/json
< Vary: Accept
< Allow: POST, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Length: 252

| {
|  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoic2xpZGluZyIsImV4cCI6MTU2NzA5NzgzNywianRpIjoiOWZkZDFkYTlkODI2NDAwNzkwNjRiYjM4Nzc5Y2FkMmQiLCJyZWZyZXNoX2V4cCI6MTU2NzE4NDE3NywidXNlcl9pZCI6Mn0.1eb5oFz6wwyjBI1wQrl5tPkkUogXWmWBBTWJn_xJC2k"
| }

I can use that token for authentication:

> GET /api/post/1 HTTP/1.1
> Host: localhost:8000
> User-Agent: insomnia/6.6.2
> Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoic2xpZGluZyIsImV4cCI6MTU2NzA5NzgzNywianRpIjoiOWZkZDFkYTlkODI2NDAwNzkwNjRiYjM4Nzc5Y2FkMmQiLCJyZWZyZXNoX2V4cCI6MTU2NzE4NDE3NywidXNlcl9pZCI6Mn0.1eb5oFz6wwyjBI1wQrl5tPkkUogXWmWBBTWJn_xJC2k
> Accept: */*

< HTTP/1.1 200 OK
< Date: Thu, 29 Aug 2019 16:57:06 GMT
< Server: WSGIServer/0.2 CPython/3.7.4
< Content-Type: application/json
< Vary: Accept
< Allow: GET, POST, HEAD, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Length: 140

| [correct response data...]

After SLIDING_TOKEN_LIFETIME (1 minute), trying to make authenticated requests gives a 401, which I would expect:

> GET /api/post/1 HTTP/1.1
> Host: localhost:8000
> User-Agent: insomnia/6.6.2
> Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoic2xpZGluZyIsImV4cCI6MTU2NzA5NzgzNywianRpIjoiOWZkZDFkYTlkODI2NDAwNzkwNjRiYjM4Nzc5Y2FkMmQiLCJyZWZyZXNoX2V4cCI6MTU2NzE4NDE3NywidXNlcl9pZCI6Mn0.1eb5oFz6wwyjBI1wQrl5tPkkUogXWmWBBTWJn_xJC2k
> Accept: */*

< HTTP/1.1 401 Unauthorized
< Date: Thu, 29 Aug 2019 17:00:27 GMT
< Server: WSGIServer/0.2 CPython/3.7.4
< Content-Type: application/json
< WWW-Authenticate: Bearer realm="api"
< Vary: Accept
< Allow: GET, POST, HEAD, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Length: 185

| {
|   "detail": "Given token not valid for any token type",
|   "code": "token_not_valid",
|   "messages": [
|     {
|       "token_class": "SlidingToken",
|       "token_type": "sliding",
|       "message": "Token is invalid or expired"
|     }
|   ]
| }

But when I try to refresh the token within SLIDING_TOKEN_REFRESH_LIFETIME:

> POST /api/users/token/refresh/ HTTP/1.1
> Host: localhost:8000
> User-Agent: insomnia/6.6.2
> Content-Type: application/json
> Accept: */*
> Content-Length: 256

| {
| 	"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoic2xpZGluZyIsImV4cCI6MTU2NzA5NzgzNywianRpIjoiOWZkZDFkYTlkODI2NDAwNzkwNjRiYjM4Nzc5Y2FkMmQiLCJyZWZyZXNoX2V4cCI6MTU2NzE4NDE3NywidXNlcl9pZCI6Mn0.1eb5oFz6wwyjBI1wQrl5tPkkUogXWmWBBTWJn_xJC2k"
| }

< HTTP/1.1 401 Unauthorized
< Date: Thu, 29 Aug 2019 17:02:53 GMT
< Server: WSGIServer/0.2 CPython/3.7.4
< Content-Type: application/json
< WWW-Authenticate: Bearer realm="api"
< Vary: Accept
< Allow: POST, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Length: 65

| {
|   "detail": "Token is invalid or expired",
|   "code": "token_not_valid"
| }

But if I try refreshing a token within SLIDING_TOKEN_LIFETIME, it works fine:

> POST /api/users/token/refresh/ HTTP/1.1
> Host: localhost:8000
> User-Agent: insomnia/6.6.2
> Content-Type: application/json
> Accept: */*
> Content-Length: 256

| {
| 	"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoic2xpZGluZyIsImV4cCI6MTU2NzA5ODM1NSwianRpIjoiNTg5ODhiMGFkMWE1NGU3MWFkOGU2NTMxZGI4ZTNhMTAiLCJyZWZyZXNoX2V4cCI6MTU2NzE4NDY5NSwidXNlcl9pZCI6Mn0.BW-qxTVupUlBogT4O-s_ySKjEdfPkl_zX7vw-d903iA"
| }

< HTTP/1.1 200 OK
< Date: Thu, 29 Aug 2019 17:05:06 GMT
< Server: WSGIServer/0.2 CPython/3.7.4
< Content-Type: application/json
< Vary: Accept
< Allow: POST, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Length: 252

| {
|   "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoic2xpZGluZyIsImV4cCI6MTU2NzA5ODM2NiwianRpIjoiNTg5ODhiMGFkMWE1NGU3MWFkOGU2NTMxZGI4ZTNhMTAiLCJyZWZyZXNoX2V4cCI6MTU2NzE4NDY5NSwidXNlcl9pZCI6Mn0.nnBpI7FDiFZOa-f4fGQC5omtff2g6WFg5NKVlE6k0CM"
| }

So am I doing something wrong? What is SLIDING_TOKEN_REFRESH_LIFETIME for? The way I expected to use a sliding token would be to retrieve a token on login, and use it for requests. Once a request returns a 401 telling me the token expired, I refresh it to obtain a new token, and repeat the process.

Thanks! Aside from refreshing sliding tokens, this library has been super easy to use :)

IvanFon avatar Aug 29 '19 17:08 IvanFon