Closed Dikymon closed 6 years ago
Hey @Dikymon, thanks for reporting. Could you provide a complete configuration of the auth module? Do you use a custom auth form or provided? And where you are trying to access the getToken()
method?
First off - thank you for a great library. Here is he auth configuration I am using
...NbAuthModule.forRoot({
strategies: [
NbPasswordAuthStrategy.setup({
name: 'email',
baseEndpoint: '/auth/',
token: {
class: NbAuthJWTToken,
key: 'token'
},
login: {
rememberMe: true,
endpoint: 'login',
method: 'post',
redirect: {
success: '/pages/main'
}
},
register: {
endpoint: 'register',
method: 'post'
},
logout: {
endpoint: 'logout',
method: 'get',
redirect: {
success: '/pages/welcome'
}
},
requestPass: {
endpoint: 'request-password',
method: 'post',
defaultErrors: [''],
defaultMessages: ['']
},
resetPass: {
endpoint: 'reset-password',
method: 'put',
resetPasswordTokenKey: 'reset_token_key',
redirect: {
success: '/',
failure: null
}
},
refreshToken: {
endpoint: 'refresh-token',
method: 'post',
redirect: {
success: null,
failure: null,
},
}
}),
],
forms: {},
}).providers
I am using a custom form, in the sense that I copied the auth components and made minor layout and wording changes. I updated those to use 'strategy' instead of 'provider' with reference to rc.9 component source - but most changes were just re-naming/typing variables.
After succesful login, the user is redirected to a page with a Guard
canActivate() {
return this.authService.isAuthenticated();
}
Subscribing to authService.getToken()
this.authService.getToken().subscribe((t: NbAuthJWTToken) => console.log(t));
yields
NbAuthSimpleToken {token: ""}
when sign-in is successful. In rc.8 it returned
NbAuthJWTToken {token: "eyJhbGciOi...."}
@Dikymon in your login.component.ts
, could you console.log
the result
variable here:
this.service.authenticate(this.strategy, this.user).subscribe((result: NbAuthResult) => {
console.log(result);
It looks to me, that the NbAuthSimpleToken {token: ""}
is an old token value currently stored under auth_app_token
key (which cannot be presented and NbAuthJWTToken
token as there is no metadata for in in the previous version token format. And it is not being overwritten by a new value coming from the server. Now we need to find out why.
Here is the output, seems okay?
errors: []
messages: ["You have been successfully logged in."]
redirect:"/pages/main"
response:
HttpResponse
body:
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAdGVzdC5kayIsInJvbG..."
user: {email: "test@test.com", role: "user"}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
ok: true
status: 200
statusText: "OK"
type: 4
url: "https://localhost/auth/login"
success: true
token: NbAuthJWTToken {token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6I…"}
Right, this part is okay. And If you check the Application -> Localstorage tab in the chrome dev tools, could you post here what is stored there under then auth_app_token
key?
The other possible issue is that it might not be able to parse the stored token for some reason here https://github.com/akveo/nebular/blob/3428ec3777afa48e87b65cd7ad47195987da0898/src/framework/auth/services/token/token-parceler.ts#L35, falling back to a default token class.
key 'app_auth_token' seems to store it correctly:
name: "nb:auth:jwt:token"
value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAdGVzdC5kayIsInJvbG...
Okay, now please open token-parceler.js
on line 23 and console.log
like this:
var tokenPack = JSON.parse(value);
console.log(tokenPack);
tokenClass = this.getClassByName(tokenPack.name) || this.fallbackClass;
console.log(tokenClass);
tokenValue = tokenPack.value;
It prints tokenPack
name: "nb:auth:jwt:token"
value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAdGVzdC5kayIsInJvbGUiOiJhZHVybyIsImZpcnN0TmFtZSI6IkFiZSIsImxhc
then throws an exception on the call to .getClassByName.
Error TypeError: this.tokenClasses.find is not a function
at NbAuthTokenParceler.push../node_modules/@nebular/auth/services/token/token-parceler.js.NbAuthTokenParceler.getClassByName (token-parceler.js:40)
at NbAuthTokenParceler.push../node_modules/@nebular/auth/services/token/token-parceler.js.NbAuthTokenParceler.unwrap (token-parceler.js:25)
at NbTokenLocalStorage.push../node_modules/@nebular/auth/services/token/token-storage.js.NbTokenLocalStorage.get (token-storage.js:56)
at NbTokenService.push../node_modules/@nebular/auth/services/token/token.service.js.NbTokenService.get (token.service.js:66)
at NbAuthService.push../node_modules/@nebular/auth/services/auth.service.js.NbAuthService.getToken (auth.service.js:28)
at NbAuthService.push../node_modules/@nebular/auth/services/auth.service.js.NbAuthService.isAuthenticated (auth.service.js:43)
at UserGuard.push../src/app/pages/pages.guard.ts.UserGuard.canActivate (pages.guard.ts:16)
Which explains the use of the fallback class.
That's great, we found the cause. What would be there if you print console.log(this.tokenClasses)
?
this.tokenClasses:
ƒ NbAuthJWTToken() {
return _super !== null && _super.apply(this, arguments) || this;
}
This is strange. It should be an array as it is provided by the NbAuthModule. Is NB_AUTH_TOKENS
by any chance provided ({ provide: NB_AUTH_TOKENS, ... }
) somewhere in your modules?
Yes! That was it. Does that conflict with in some way?
Thank you so much for your help, I hope it was not a complete waste of your time.
Yes! That was it. Does that conflict with in some way?
Starting with rc.9 there is no need to provide a token (or tokens) anymore, just mention it in the strategy configuration
({ token: { class: NbSomeTokenClass } }
and it will do the rest.
No problem, glad we resolved it.
I will leave the issue opened as supressing all of the errors in the token parceler class looks like a not very good idea as it hides such issues.
Issue type
I'm submitting a ... (check one with "x")
Issue description
Current behavior: After upgrading from rc.8 to rc.9 and refactoring to use the new Auth strategy, the JWT token emitted from NbAuthService.getToken() is empty (type NbAuthSimpleToken) after a succesful sign-in. I have verified that the token is correctly returned from the 'token.getter' method. What am i missing?
Expected behavior: Token is emitted on AuthService.getToken() as in rc.8.
Related code:
Angular, Nebular