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

Upgrading from rc.8 to rc.9 - JWT tokens not being stored by NbAuthService? #528

Closed
1 of 2 tasks
Dikymon opened this issue Jun 26, 2018 · 13 comments · Fixed by #548
Closed
1 of 2 tasks

Upgrading from rc.8 to rc.9 - JWT tokens not being stored by NbAuthService? #528

Dikymon opened this issue Jun 26, 2018 · 13 comments · Fixed by #548

Comments

@Dikymon
Copy link

Dikymon commented Jun 26, 2018

Issue type

I'm submitting a ... (check one with "x")

  • bug report
  • feature request

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:

NbPasswordAuthStrategy.setup({
        name: 'email',
        baseEndpoint: '/auth/',
        token: {
          class: NbAuthJWTToken,
          key: 'token'
        },
        ....


Angular, Nebular

Angular 6, Nebular rc.9

<!--
Check your `package-lock.json` or locate a `package.json` in the `node_modules` folder.
-->
@nnixaa
Copy link
Collaborator

nnixaa commented Jun 26, 2018

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?

@Dikymon
Copy link
Author

Dikymon commented Jun 26, 2018

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...."}

@nnixaa
Copy link
Collaborator

nnixaa commented Jun 26, 2018

@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.

@Dikymon
Copy link
Author

Dikymon commented Jun 26, 2018

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…"}

@nnixaa
Copy link
Collaborator

nnixaa commented Jun 26, 2018

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

const tokenPack: NbTokenPack = JSON.parse(value);
, falling back to a default token class.

@Dikymon
Copy link
Author

Dikymon commented Jun 26, 2018

key 'app_auth_token' seems to store it correctly:

name: "nb:auth:jwt:token"
value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAdGVzdC5kayIsInJvbG...

@nnixaa
Copy link
Collaborator

nnixaa commented Jun 26, 2018

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;

@Dikymon
Copy link
Author

Dikymon commented Jun 26, 2018

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.

@nnixaa
Copy link
Collaborator

nnixaa commented Jun 26, 2018

That's great, we found the cause. What would be there if you print console.log(this.tokenClasses)?

@Dikymon
Copy link
Author

Dikymon commented Jun 26, 2018

this.tokenClasses:

ƒ NbAuthJWTToken() {
        return _super !== null && _super.apply(this, arguments) || this;
    }

@nnixaa
Copy link
Collaborator

nnixaa commented Jun 26, 2018

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?

@Dikymon
Copy link
Author

Dikymon commented Jun 26, 2018

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.

@nnixaa
Copy link
Collaborator

nnixaa commented Jun 26, 2018

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.

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

Successfully merging a pull request may close this issue.

2 participants