usefulteam / jwt-auth

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

Refresh Token #1

Closed mostafasoufi closed 2 years ago

mostafasoufi commented 4 years ago

I realized the plugin doesn't support the refresh token which is important for renewing the token in the next requests. so the question is, do you have any plan to add the refresh token in your endpoints?

https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

contactjavas commented 4 years ago

Hi @mostafasoufi , yep i'm aware of this limitation. I'm going to support it. Might be part of version 2.0

mostafasoufi commented 4 years ago

Look at this article, It might be useful while implementation.

https://dev.to/gokayokyay/api-authentication-workflow-with-jwt-and-refresh-tokens-5312

alexcorvi commented 4 years ago

I'm also interested in this feature! great plugin by the way!

jxunaied commented 4 years ago

refresh token is necessary. please implement it

runebakjacobsen commented 4 years ago

Any update on this?

mostafasoufi commented 4 years ago

I implemented the refresh token in a separated plugin and maybe I could be useful for you https://github.com/codelight-eu/wp-api-jwt-auth/blob/master/public/class-jwt-auth-public.php#L93

runebakjacobsen commented 4 years ago

I implemented the refresh token in a separated plugin and maybe I could be useful for you https://github.com/codelight-eu/wp-api-jwt-auth/blob/master/public/class-jwt-auth-public.php#L93

Oh cool, thanks! I'll take a look.

contactjavas commented 3 years ago

Gonna work on refresh token this week. Putting a link here as a reference.

valstu commented 3 years ago

Any updates on this? Is this worked on PR #19?

sun commented 3 years ago

In a quest to find a working implementation for refresh tokens I had to study all the proposed solutions thus far. Here's what I found – hopefully this will help to move this important topic forward:

The effective diff of @mostafasoufi's changes against the source repo (which is a different plugin than this jwt-auth plugin/repo) can be seen here: https://github.com/Tmeister/wp-api-jwt-auth/compare/develop...codelight-eu:master?w=1

That plugin has 127 forks on GitHub. I did not check yet whether there might be a proper and working implementation in one of the other forks.

The effective diff of #19 can be seen here (unfortunately the branch reformats all code, which could and should have been proposed as a separate PR): https://github.com/usefulteam/jwt-auth/pull/19/files?w=1

There are 19 forks of this plugin on GitHub. I also did not check those yet.

sun commented 3 years ago

33 now implements a proper refresh token architecture for this plugin. Reviews welcome.

I reimplemented the good ideas from aforementioned attempts, as outlined in my previous comment - and completed the picture with an actual concept of refresh tokens.

The general idea is that the client should not store the username/password credentials themselves. It should only store the refresh token. The common flow looks like this:

Authenticate with actual user login credentials

$ curl -X POST -F username=user -F password=pass https://example.com/wp-json/jwt-auth/v1/token
{
  "success": true,
  "statusCode": 200,
  "code": "jwt_auth_valid_credential",
  "message": "Credential is valid",
  "data": {
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvc2VydmljZS50ZXN0LmJubi5kZSIsImlhdCI6MTYyNDQ1NzA2MSwibmJmIjoxNjI0NDU3MDYxLCJleHAiOjE2MjQ0NjA2NjEsImRhdGEiOnsidXNlciI6eyJpZCI6NTA1NjUsImRldmljZSI6IiIsInBhc3MiOm51bGx9fX0.yYmLkcoF6mYoI6naAUv_qvOgfojm2cTG3HW-CvSkkj0",
    ...
    "refreshToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvc2VydmljZS50ZXN0LmJubi5kZSIsImlhdCI6MTYyNDQ1NzA2MSwibmJmIjoxNjI0NDU3MDYxLCJleHAiOjE2MjcwNDkwNjEsImRhdGEiOnsidXNlciI6eyJpZCI6NTA1NjUsImRldmljZSI6IiIsInBhc3MiOiJkZGU1YThlM2ZmYjQ2ZTBiNzY4OWI5M2QwNzk0MTk5OCJ9fX0.UNlvDB2p601BNXDa-OBtt5jnXjttx0bL7VhHDyud8-E"
  }
}

Validate the (refresh or short-lived access) token before it expires

$ curl -X POST -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvc2VydmljZS50ZXN0LmJubi5kZSIsImlhdCI6MTYyNDQ1NzA2MSwibmJmIjoxNjI0NDU3MDYxLCJleHAiOjE2MjcwNDkwNjEsImRhdGEiOnsidXNlciI6eyJpZCI6NTA1NjUsImRldmljZSI6IiIsInBhc3MiOiJkZGU1YThlM2ZmYjQ2ZTBiNzY4OWI5M2QwNzk0MTk5OCJ9fX0.UNlvDB2p601BNXDa-OBtt5jnXjttx0bL7VhHDyud8-E' https://example.com/wp-json/jwt-auth/v1/token/validate
{
  "success": true,
  "statusCode": 200,
  "code": "jwt_auth_valid_token",
  "message": "Token is valid",
  "data": {...}
}

Refresh the access token using the refresh token

$ curl -X POST -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvc2VydmljZS50ZXN0LmJubi5kZSIsImlhdCI6MTYyNDQ1NzA2MSwibmJmIjoxNjI0NDU3MDYxLCJleHAiOjE2MjcwNDkwNjEsImRhdGEiOnsidXNlciI6eyJpZCI6NTA1NjUsImRldmljZSI6IiIsInBhc3MiOiJkZGU1YThlM2ZmYjQ2ZTBiNzY4OWI5M2QwNzk0MTk5OCJ9fX0.UNlvDB2p601BNXDa-OBtt5jnXjttx0bL7VhHDyud8-E' https://example.com/wp-json/jwt-auth/v1/token/refresh
{
  "success": true,
  "statusCode": 200,
  "code": "jwt_auth_valid_credential",
  "message": "Credential is valid",
  "data": {
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvc2VydmljZS50ZXN0LmJubi5kZSIsImlhdCI6MTYyNDQ2MzY2OCwibmJmIjoxNjI0NDYzNjY4LCJleHAiOjE2MjQ0NjcyNjgsImRhdGEiOnsidXNlciI6eyJpZCI6NTA1NjUsImRldmljZSI6IiIsInBhc3MiOiJkZGU1YThlM2ZmYjQ2ZTBiNzY4OWI5M2QwNzk0MTk5OCJ9fX0.itnlJVr9eMkMLzFtJR26rkNFfO1A7ZSDSp1ptze9uME",
    ...
  }
}

Note: The /token/refresh response only supplies a new access token. It does not generate a new refresh token.

sun commented 3 years ago

After studying the docs from various authentication service providers, I updated the PR https://github.com/usefulteam/jwt-auth/pull/33 to send and accept the refresh token only in a HttpOnly cookie to meet common security considerations for web based clients.

holygekko commented 3 years ago

I understand it's best practice to store the refresh token in a HttpOnly cookie, however when using wp as a backend for a mobile app it would be undesirable. Cookies can be removed automatically by the mobile os without notice and being HttpOnly the cookie can't be read client side and can't be stored in persistent storage. Is it possible to make this configurable?

sun commented 3 years ago

@holygekko Sure, we can add an option or constant to emit the refresh token in the response body instead.

Most JWT / HTTP client libraries should support to read the response HTTP headers though. The HttpOnly flag only means that the cookie can't be accessed via JavaScript – it's a normal cookie for regular backends otherwise. We're currently integrating this for a mobile app that is using the OkHttp library; I don't have access to the client code, but it seems to be possible without issues.