-
Notifications
You must be signed in to change notification settings - Fork 140
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
Update refresh strategy to use a separate refresh token #190
Conversation
…esh the JWT Made makeRefreshToken use the refresh token propert name to create it's object updated tests to deal with new refresh token method
@evoactivity thank you for your work! I've looked at the test and the implementation and it looks good. I think that we should wait until @jpadilla can take a look at this before we merge the PR. This is a breaking change so we'll need to update the docs and demo too. We can do that after @jpadilla takes a look. |
@eluciano11 No problem :) I was wondering about the docs/demos, but decided against updating them until this had been reviewed incase there are any changes needed. |
@@ -120,11 +122,11 @@ export default TokenAuthenticator.extend({ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (Ember.isEmpty(expiresAt)) {
// Fetch the expire time from the token data since `expiresAt`
// wasn't included in the data object that was passed in.
const tokenData = this.getTokenData(token);
expiresAt = tokenData[this.tokenExpireName];
if (Ember.isEmpty(expiresAt)) {
return resolve(data);
}
}
if (expiresAt > now) {
Shouldn't we be checking if the refresh token expiresAt > now
rather than the auth token expiresAt > now
?
With the way it currently is, if the auth token expired but the refresh token has not expired, it would not attempt to refresh.
I think we would want to attempt to refresh if the refresh token is still valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My API's refresh token library creates the token like so $this->refreshToken = bin2hex(openssl_random_pseudo_bytes(64));
, so the refresh token is not just another JWT with an expires property to be decoded. Looking at the auth0 page on refresh tokens it looks like they're implementing them in a similar way https://auth0.com/learn/refresh-tokens/
If the auth token is expired that's exactly when this tries to refresh using the refresh token, so I'm not entirely sure what you mean by that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I am seeing, if the auth token is expired when it enters the restore function then it will reject on line 132
reject(new Error('token is expired'));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, I see what you mean now, my mistake.
I guess if the token is expired and we have refreshAccessTokens
set to true it should also attempt to refresh the token there as well, and if the server rejects the refresh token then the user is unauthorised sending them back to the login form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sorry for the confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@evoactivity Do you have time to implement the fix for this? I am considering forking off, I will be trying to use this feature in an app for this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alechirsch I will be looking at this again maybe later today or tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alechirsch I've updated this to attempt a refresh if the JWT is expired. If the server rejects the request the session is invalidated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@evoactivity Awesome, thanks for your work on this, it is perfect timing.
@evoactivity At a first pass, this lgtm. Thanks for putting this together. I'm fine introducing this as a new major release, but would also love to sneak in updating everything else including to the latest ESA. |
@jpadilla no worries :) I've just pushed a small update to address the expiry issue pointed out by @alechirsch The docs will need updating to explain the new The demo app should probably be updated to show this being used, the demo server will need to return two tokens now, the JWT and a standard refresh token. |
@jpadilla @evoactivity yup, updated the docs and the demo app but it's not using the two tokens it's falling back to the old strategy. |
I just did some testing in my own application, there seems to be an issue with old timeouts not being removed. I will do more testing to find out what is really going on. |
@evoactivity From what I am finding if you log in then refresh the page to make it call restore, it will refresh the token, and then call restore again exponentially. Meaning it calls restore once, then twice, then 4 times, then 8. Something about Restore should be called only once, when the page is refresh or opened in a new tab. I am unsure why this is happening at the moment. |
@alechirsch I've not seen that behaviour at all in my own app. What sort of expiry time do you have on your JWT? Also, what leeway do you have set? |
For testing purposes I set it to 60 seconds, with 55 second leeway. Maybe that is the problem? |
I've been testing with my JWT set to 1 minute and my refresh token set to 2 minutes and my leeway set to 0. I'm not sure why a 5 second expiry would call exponential calls to refreshAccessToken though. |
What's odd is that the restore function is being called more than once. |
I blew away my node_modules and reinstalled, set my expire to 10 minutes and leeway to 60 seconds. I am running into the same problem, the restore function is being called in an infinite loop somehow. It works great if the restore function rejects the first time it is hit, however if it resolves, it calls itself again. It hogs up the CPU at 100% as well. |
I have traced it back to this file The beforeModel hook is being called on an infinite loop, which is in turn calling restore. This might be a problem with my app, looking into it more. |
@evoactivity It was definitely a problem with my application, the feature works as expected now. |
This is the current server implementation that the dummy app uses https://github.com/jpadilla/ember-simple-auth-token-server |
What is currently holding up this PR? I have been using this for the past few weeks in my apps and it works perfectly by the way. |
@alechirsch thanks for bumping this again, great to know you've been using it for a while now. Since this is a breaking change, it'll be released on v3, but before doing so I would love to make sure we update ember-cli, ESA, etc. Thanks to all! PS If anyone else wants to help with that before I do, please feel free to do so. Thanks! |
@homu r+ |
📌 Commit 765e926 has been approved by |
⚡ Test exempted - status |
Update refresh strategy to use a separate refresh token As discussed in this issue #162 I've made the library use a separate token to refresh the JWT. I've updated the tests and they all pass but someone should really check what I've done, testing is not my strong point. I've ran this on my app and confirmed it refreshes the token as expected.
@alechirsch @evoactivity I'm looking for help with maintenance, would any of you be up to it? |
@jpadilla I can help out with pull requests and issues |
@alechirsch that's so great, just sent you an invite, thank you so much! |
@jpadilla I'm too busy to offer much help at the moment but I'd be interested in helping when things settle down a bit for me. That's probably a month or two away though. |
@evoactivity understandable! Feel free to ping back whenever you have a few cycles free, thanks! |
This is a breaking change, because if the refreshToken name isn't set it defaults to |
Thank you all again! Just released v3.0.0 🎉 |
As discussed in this issue #162 I've made the library use a separate token to refresh the JWT.
I've updated the tests and they all pass but someone should really check what I've done, testing is not my strong point.
I've ran this on my app and confirmed it refreshes the token as expected.