Search code examples
angularoauth-2.0hash-location-strategy

Handling OAuth2 Implicit Redirect with Angular Routing using HashLocationStrategy


I'm enabling OAuth2 on an SPA as follows:

  • The implicit grant type is the only grant type supported
  • My Angular 5 app uses HashLocationStrategy for its routing

I cannot change either of these constraints.

When I log in to my app and get redirected, the redirect url from the authorize endpoint looks like this:

http://foo/#access_token=(ey...)&token_type=bearer&state=(state...)&expires_in=43199&jti=(jti...)

This is as expected according to the OAuth2 spec; the parameters present in the redirect url must be appended as a fragment (following the '#').

The problem I'm having is that Angular is interpreting the characters following the hash according to its hash location strategy. It is attempting to redirect to path access_token=... which does not exist.

How do I get around this?


Solution

  • You need to tell the router to cut with it's shenanigans until you're done processing the URL. Here's how:

    imports: [
      ..
      RouterModule.forRoot(routes, { initialNavigation: false }),
    ],
    ...
    

    Now the nosey router will not do anything on page load. Which means that you have to take care of it! Go parse your OAuth state, tokens etc. Then figure out what route were you trying to get to (e.g. from redirectUrl, some part of the fragment itself, something from localStorage from before navigating away for auth, or similar. Once you've done that, call the router, tell it to resume:

    this.accessToken = this.url....
    this.router.navigate('wherever-you-wanted-to-go-in-the-first-place');