-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Feat/auth improvement : refresh-token are now saved if not repeated by the backend refresh endpoint #593
Feat/auth improvement : refresh-token are now saved if not repeated by the backend refresh endpoint #593
Conversation
Now : If existing, NbAuthResult contains backend error description other Changes requested by Dmitry (first review)
Now : If existing, NbAuthResult contains backend error description other Changes requested by Dmitry (first review) +tslint missing trailing comma arghhh
…strategy used to create the token (future use)
The token now contains ownerStrategyName, with is a back link to the strategy used to create the token (future use). BREAKING CHANGE : NbAuthCreateToken (token.ts) now takes a third parameter, which is the ownerStrategyName Tokens are created by strategies that are called from services, so it is *potentially* a breaking change.
The token now contains ownerStrategyName, with is a back link to the strategy used to create the token (future use). updated unit tests files and oauth2-password-login.component (breaking change below) BREAKING CHANGE : NbAuthCreateToken (token.ts) now takes a third parameter, which is the ownerStrategyName Tokens are created by strategies that are called from services, so it is *potentially* a breaking change.
removed useless code and cleaned one unit test file BREAKING CHANGE : NbAuthCreateToken (token.ts) now takes a third parameter, which is the ownerStrategyName Tokens are created by strategies that are called from services, so it is *potentially* a breaking change.
Tokens can now be asked for their creation date via createdAt attribute or getCreatedAt() NbAuthOAuth2Token.getTokenExpDate() now returns a correct expDate (Issue #564) Unit tests updated nnixaa first review nnixaa second review nnixaa third review (am i so bad ? :-p)
A new class of token has been defined. NbAuthOAuth2JWTToken : class to use when your auth backend sends Oauth tokens encapsulating a jwt access token.
# Conflicts: # src/framework/auth/services/token/token.ts Optimized token.ts code
# Conflicts: # src/framework/auth/services/token/token.ts Optimized token.ts code
@@ -16,11 +16,19 @@ export abstract class NbAuthToken { | |||
|
|||
export interface NbAuthRefreshableToken { | |||
getRefreshToken(): string; | |||
// Needed when refresh-token response does not repeat refresh_token value |
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.
@alain-charles so it is possible that after refreshing the token server may not return a new refresh token? Just looked through the RFC and this part looks vague.
In any case, I would propose to move this functionality into the refreshToken()
method of the strategy. In this case, we have the current token and can extract the refresh part right there with no need for all additional checks.
What do you think?
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.
I think that you are a amazing code architect :)
reverted token, token-service and corresponding spec.ts files
Codecov Report
@@ Coverage Diff @@
## master #593 +/- ##
==========================================
+ Coverage 72.8% 72.85% +0.04%
==========================================
Files 153 153
Lines 4207 4214 +7
Branches 317 318 +1
==========================================
+ Hits 3063 3070 +7
Misses 1087 1087
Partials 57 57
|
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.
@alain-charles one last change
@@ -199,13 +199,17 @@ export class NbOAuth2AuthStrategy extends NbAuthStrategy { | |||
return this.http.post(url, this.buildRefreshRequestData(token), this.buildAuthHeader()) | |||
.pipe( | |||
map((res) => { | |||
const refreshedToken = <NbAuthOAuth2Token>this.createToken(res); |
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.
let's just move this into a new method:
createRefreshedToken(res): NbAuthRefreshableToken {
...
}
and then call it almost as before:
return new NbAuthResult(
true,
res,
this.getOption('redirect.success'),
[],
this.getOption('defaultMessages'),
this.createRefreshedToken(res));
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.
@nnixaa
I think you mean
createRefreshedToken(res, existingToken): NbAuthOAuth2Token {
...
}
since we need the existing token for extracting the existing refresh_token
And NbAuthOAuth2Token instead of NbAuthRefreshableToken so that we return something assignable to NbAuthResult.token i.e NbAuthToken
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.
@alain-charles yes, of course, you are right.
But in the second part - return NbAuthOAuth2Token
- is this always true? as by design we can assign any token to any strategy, so it is not necessary NbAuthOAuth2Token
, but rather NbAuthToken
.
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.
@nnixaa here is the best implementation i have found
protected createRefreshedToken(res, existingToken: NbAuthRefreshableToken): NbAuthToken {
const refreshedToken = this.createToken(res);
if (isNbAuthRefreshableToken(refreshedToken)
&& !refreshedToken.getRefreshToken()
&& existingToken.getRefreshToken()) {
refreshedToken.setRefreshToken(existingToken.getRefreshToken());
}
return refreshedToken;
}
i think this is the one that is the most in the spirit of your architecture
authService : corrected the strategy.refreshToken() call : we were forgettong to pass data as argument ?! token : added isNbAuthRefreshableToken(token) method
@@ -376,6 +377,16 @@ export class NbOAuth2AuthStrategy extends NbAuthStrategy { | |||
}, {}) : {}; | |||
} | |||
|
|||
protected createRefreshedToken(res, existingToken: NbAuthRefreshableToken): NbAuthToken { |
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.
I believe we can leave this check as:
if (!refreshedToken.getRefreshToken() && existingToken.getRefreshToken()) {
as we can only have the NbAuthRefreshableToken
token here, which presumes that both required get and set method exist because this method could only be called from the refreshToken
one, which cannot be called for a non-refreshable token.
In case when the developer forces a call of refreshToken
method for a non-refreshble token it will be a typescript level error, which is completely fine in this case.
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.
!refreshedToken.getRefreshToken()
does not compile as NbAuthToken
(the return type) does not implement this method.
That is the reason why i added the isNbAuthRefreshableToken(refreshedToken)
test
So what do you prefer :
- should we return NbAuthOauth2Token ?
- or just cast in the body of the method the refreshedToken to NbAuth0Auth2Token ?
- or leave the code like in #10d0b31 commit ?
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.
@alain-charles can we do this:
protected createRefreshedToken(res, existingToken: NbAuthToken & NbAuthRefreshableToken)
Sorry not able to check it myself.
If we can't, let's leave it as your current version.
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.
@alain-charles sorry for the delay, wrote the comment last Thursday but forgot to submit.
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.
@nnixaa with the intersection type you propose above, the problem remains on refreshedToken
const refreshedToken = this.createToken(res);
this.createToken(res)
returns NbAuthToken
that does not implement getRefreshToken()
.
Any other idea ?
Alain
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.
@alain-charles something like this probably? https://github.com/alain-charles/nebular/pull/1/files
…freshToken refactor(token): generic type for `createToken` method
@alain-charles cool! |
Feature/Auth : improvement on refreshable tokens
Short description of what this resolves:
At log on, some backends send Oauth2 token with a refresh-token value.
But some of them do no repeat the refresh token value when you then hit the refresh token endpoint.
So up to now, we were losing the refresh-token so that we were unable to send more than once a refresh token request
This PR corrects this problem: if necessary , it gets the existing refresh-token value in the current token and injects it in the refreshed token before storing it.
Hope it helps.