Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal Guardian Refresh Tokens #111

Closed
Hanspagh opened this issue Feb 13, 2016 · 12 comments
Closed

Proposal Guardian Refresh Tokens #111

Hanspagh opened this issue Feb 13, 2016 · 12 comments

Comments

@Hanspagh
Copy link
Contributor

A common use case for many api's that are consumed by mobile app's is to get a new token without re-authenticating to avoid contentiously prompt users with login screens. This is most commonly done with refresh tokens. Would it be an idea to make a project similar to GuardianDb to implement this behavior?

@hassox
Copy link
Member

hassox commented Feb 15, 2016

Hey @Hanspagh. Guardian provides a refresh! function. Checkout Guardian.refresh!

@Hanspagh
Copy link
Contributor Author

Yes, I know but that only allows us to make a new token from an valid existing one. The feature I am requesting is to create a new token without having a valid token, but from a refresh token. Like described here https://auth0.com/docs/refresh-token

@hassox
Copy link
Member

hassox commented Feb 16, 2016

Refresh tokens are tricky. There's a couple of ways to do them that spring to mind.

  1. Create a non-expiring token containing/mapping the 'claims' and store it in the db. When issuing a JWT from it, use the claims from the refresh token and encode them into an access token. This requires that you have a database and lookup the refresh token. This method would be outside the scope of Guardian since you'd have to maintain some state on your server.
  2. Create a token with Guardian of type 'refresh' that has a long expiry (years) containing all claims required. You can then use this token to exchange for a type of 'access' containing the same claims with a much shorter exp. This does not require you to store the token in a db - although you should probably use something like GuardianDb so that it can be revoked. This would require the addition of an 'exchange' function in guardian so that you could exchange one type of token for another.

I'd be down for adding an exchange function I think. It's been on my todo list for a while I just haven't had the motivation to actually write it.

Thoughts?

@Hanspagh
Copy link
Contributor Author

My first thought was to implement it like you described in 1. and then add it as dependency like GuardianDb.

But 2. seems to integrate much better into the existing code and being able to reuse GuardianDb instead of writing a db integration again seems to be a big win.
I am still a bit new to Elixir but I would be happy to help with implementing this :)

@hassox
Copy link
Member

hassox commented Feb 17, 2016

@Hanspagh I'd be happy to review something for #1 but I don't think it should go into the Guardian lib.

@Hanspagh
Copy link
Contributor Author

When you say it should not go in the Guardian lib, do you then mean it should be a lib like GuardianDb or should it be part of the core.

@hassox
Copy link
Member

hassox commented Feb 18, 2016

I think it should be a separate lib like guardian db

@Hanspagh
Copy link
Contributor Author

Awesome, Will start working on something

@hassox
Copy link
Member

hassox commented Feb 19, 2016

Sounds great. I'd love to see it when you have something.

@hassox hassox closed this as completed Feb 19, 2016
@Hanspagh
Copy link
Contributor Author

Hanspagh commented Mar 4, 2016

I made a VERY simple initial commit on the Refresh Token project, and I thought you might wanted to take a quick look at it, just to see if I am on the right track.
https://github.com/Hanspagh/guardian_refresh_token

@nambrot
Copy link

nambrot commented Aug 22, 2016

Has there been any progress on providing a solution for refresh tokens, or at least a recommended way of doing it yourself?

@Hanspagh
Copy link
Contributor Author

We are currently working on it.
But you can use encode_and_sign to create tokens with a 'refresh type' and a longer expire time.

claims = Guardian.Claims.app_claims |> Guardian.Claims.ttl({60, :days})
{:ok, jwt, claims} = Guardian.encode_and_sign(resource, "refresh", claims)

Later you can verify that a token is a 'refresh token' and issue a shorter living access token.
case Guardian.decode_and_verify(jwt) do
{ :ok, claims } -> #verify that the type is refresh and issue a new access token
end

Hope this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants