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

Access token doesn't handled in router configured with "useHash: true" #211

Closed
bezigon opened this issue Oct 28, 2016 · 7 comments
Closed
Labels

Comments

@bezigon
Copy link

bezigon commented Oct 28, 2016

* Navigated to http://localhost:4200/
router_module.js:224 -> Router Event: NavigationStart
router_module.js:225 -> NavigationStart(id: 1, url: '/')
lang.js:124 -> Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
router_module.js:224 -> Router Event: RoutesRecognized
router_module.js:225 -> RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
router_module.js:224 -> Router Event: NavigationEnd
router_module.js:225 -> NavigationEnd(id: 1, url: '/', urlAfterRedirects: '/home')
* Navigated to https://accounts.google.com/AccountChooser?(…)
* Navigated to http://localhost:4200/
router_module.js:224 -> Router Event: NavigationStart
router_module.js:225 -> NavigationStart(id: 1, url: '/access_token')
lang.js:124 -> Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
router_module.js:224 -> Router Event: RoutesRecognized
router_module.js:225 -> RoutesRecognized(id: 1, url: '/access_token', urlAfterRedirects: '/access_token', state: Route(url:'', path:'') { Route(url:'access_token', path:'**') } )
router_module.js:224 -> Router Event: NavigationEnd
router_module.js:225 -> NavigationEnd(id: 1, url: '/access_token', urlAfterRedirects: '/access_token')
router_module.js:224 -> Router Event: NavigationStart
router_module.js:225 -> NavigationStart(id: 2, url: '/')
router_module.js:224 -> Router Event: RoutesRecognized
router_module.js:225 -> RoutesRecognized(id: 2, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
router_module.js:224 -> Router Event: NavigationEnd
router_module.js:225 -> NavigationEnd(id: 2, url: '/', urlAfterRedirects: '/home')
auth.service.ts:36 -> [LOG lock on] authenticated => Object {accessToken: "", idToken: undefined, idTokenPayload: undefined, refreshToken: undefined, state: undefined}
auth.service.ts:40 -> [LOG lock get profile] error => Error: Invalid token(…)
auth.service.ts:24 -> [LOG tokenNotExpired try/catch ex] Error: JWT must have 3 parts(…)
router_module.js:224 -> Router Event: NavigationStart
router_module.js:225 -> NavigationStart(id: 3, url: '/')
router_module.js:224 -> Router Event: RoutesRecognized
router_module.js:225 -> RoutesRecognized(id: 3, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
router_module.js:224 -> Router Event: NavigationEnd
router_module.js:225 -> NavigationEnd(id: 3, url: '/', urlAfterRedirects: '/home')

Whereas for router configured with "useHash: false" all is working fine.

Solution?

@bezigon
Copy link
Author

bezigon commented Oct 28, 2016

BTW there is my router's config:

import { NgModule } from '@angular/core'
import { RouterModule, Route, ExtraOptions } from '@angular/router'
import { HomeComponent } from './home/home.component'
import { PingComponent } from './ping/ping.component'
import { PageNotFoundComponent } from './page-not-found/page-not-found.component'

@NgModule({
  imports: [
    RouterModule.forRoot([
      <Route>{ path: '', pathMatch: 'full', redirectTo: 'home' },
      <Route>{ path: 'home', component: HomeComponent },
      <Route>{ path: 'ping', component: PingComponent },
      <Route>{ path: '**', component: PageNotFoundComponent },
    ], <ExtraOptions>{
      enableTracing: true,
      // useHash: true,
      })
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule {
}

@bezigon
Copy link
Author

bezigon commented Oct 28, 2016

With <Route>{ path: '**', component: PageNotFoundComponent } commented out:

* Navigated to http://localhost:4200/
router_module.js:224 -> Router Event: NavigationStart
router_module.js:225 -> NavigationStart(id: 1, url: '/')
lang.js:124 -> Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
router_module.js:224 -> Router Event: RoutesRecognized
router_module.js:225 -> RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
router_module.js:224 -> Router Event: NavigationEnd
router_module.js:225 -> NavigationEnd(id: 1, url: '/', urlAfterRedirects: '/home')
* Navigated to https://accounts.google.com/AccountChooser?(…)
* Navigated to http://localhost:4200/
router_module.js:224 -> Router Event: NavigationStart
router_module.js:225 -> NavigationStart(id: 1, url: '/access_token')
lang.js:124 -> Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
router_module.js:224 -> Router Event: NavigationError
router_module.js:225 -> NavigationError(id: 1, url: '/access_token', error: Error: Cannot match any routes. URL Segment: 'access_token')

@ghost
Copy link

ghost commented Dec 4, 2016

+1 (I confirm this issue)

1 similar comment
@dtavera
Copy link

dtavera commented Dec 7, 2016

+1 (I confirm this issue)

@escardin
Copy link
Contributor

escardin commented Dec 8, 2016

Can one of you make a plunk that reproduces the issue?

@escardin escardin added the bug label Dec 19, 2016
@stefanruijsenaars
Copy link

To reproduce, use the auth0 angular2 demo repo and add { useHash: true } as a second parameter to RouterModule.forRoot()

@chenkie
Copy link
Contributor

chenkie commented Jan 14, 2017

This issue happens because Angular's router doesn't play nicely with the redirect flow and authentication result that comes in the hash. For Lock versions between 10.0.0 and 10.9.2, this can be solved by listening for router events, parsing the hash if one is found, and using the authentication result. See this workaround for more.

For Lock > 10.9.2, a resumeAuth function will be included which can be combined with the approach in the link above. The method you'd use would look like this:

...
import 'rxjs/add/operator/take';
import 'rxjs/add/operator/filter';

public handleAuthenticationWithHash(): void {
  this
    .router
    .events
    .filter(event => event.constructor.name === 'NavigationStart')
    .filter(event => (/access_token|id_token|error/).test(event.url))
    .subscribe(event => {
      this.lock.resumeAuth(window.location.hash, (error, authResult) => {
        if (error) return console.log(error);
        this.setUser(authResult);
        this.router.navigateByUrl('/');
      });
  });
}

private setUser(authResult): void {
  localStorage.setItem('access_token', authResult.accessToken);
  localStorage.setItem('id_token', authResult.idToken);
}

This can be called in the AppComponent

import { AuthService } from './auth/auth.service';
...
export class AppComponent {
  constructor(public auth: AuthService) {
    auth.handleAuthenticationWithHash();
  }
}

This issue isn't specific to angular2-jwt but rather Auth0 Lock. I'll close this here, but stay tuned to the Lock issue tracker for more.

@chenkie chenkie closed this as completed Jan 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants