usefulteam / jwt-auth

WordPress JSON Web Token Authentication
https://wordpress.org/plugins/jwt-auth/
116 stars 49 forks source link

Intended workflow with access/refresh token #123

Closed davidhealey closed 2 months ago

davidhealey commented 2 months ago

I'm just getting ready to update to v3 and reading through the docs I have a couple of questions.

Currently in my desktop app, the user enters their username and password and clicks submit. This is sent off to the /token endpoint and I get a token which I then pass along with all future requests.

From what I understand in the docs, with v3 I do the same thing, but instead of getting a token I can pass along with future requests I get a token that I use to get another token that I can pass along with future requests. Is that correct?

Since the new token is only valid for 10 minutes, I'll need to get a new one before each request (or running a check to see if it's still valid). Is this correct?

Assuming this is correct. How does it make the system overall more secure? Is it because of the new device parameter?

One big problem I am concerned with is I'll need to update my app for it to make the extra requests, but this will mean everyone using the previous version of the app will run into login issues. Is it possible to make v3 work like the old version so I don't have to do this?

dominic-ks commented 2 months ago

Hi @davidhealey, thanks for the questions.

Firstly, if you would like to continue using the plugin as in previous versions, you can use the jwt_auth_expire hook to set token expiry times to be for a longer time, in which case it will work in the same way it does now, i.e. the token expires and users need to log back in again.

As for your main question, that's not quite right. Calls to the /jwt-auth/v1/token and /jwt-auth/v1/token/validate endpoints will work in largely the same way if you want them to.

Calls to /jwt-auth/v1/token will have the same response, except that it will also come with a refresh_token cookie. You use the access_token in the same way. When the access_token is expired, or due to expire, or any time you choose, you can send another request to /jwt-auth/v1/token, this time with no POST body, but with the refresh_token cookie, this will return a new access_token to continue using as normal.

You can subsequently get a new refresh token by sending the refresh_token cookie to /jwt-auth/v1/token/refresh, this will give you a new refresh_token.

The reason that this is more secure, is that if a token with a longer life is obtained by a bad actor, they will have access to a system for the entire duration of its validity. If the token is only valid for 10 mins, that is the length of time a bad actor could misuse the system. Additionally, using refresh tokens to generate new access tokens means that the user's actual login credentials are only sent at the start of the flow, meaning they are less likely to be exposed.

davidhealey commented 2 months ago

Aha I see. I thought the token I was seeing in the response of v3 was the refresh token, I didn't realise that was a separate cookie. Cookies aren't applicable to my desktop app so I'll stick with the old way of doing things and extend the time out.

dominic-ks commented 2 months ago

Yes and that point has been mentioned in #115 to include the refresh_token in the JSON response, which I think is a good idea.