Kay
Kay

Reputation: 19708

How to redirect a user to their intended url after logging in with auth0 lock

Goal: If a user navigates to a protected link they should be given the auth0 lock popup to login and be redirected to their intended destination.

I have a protected route /reports which is protected via an authguard service.

auth.guard.ts

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(
        private authService: AuthService,
        private router: Router,
        private snackBar: MatSnackBar,
    ) {

    }

    canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

        if (!this.authService.isAuthenticated()) {

            this.authService.login(state.url);

            return false;
        }
        return true;
    }
}

The guard attempts to login passing in the state.url ( which is where the user intended to go, before being prompted to login).

auth.service.ts

@Injectable()
export class AuthService {


    lock = new Auth0Lock(
        environment.auth.clientID,
        environment.auth.domain,
        environment.auth.auth0Options,
    );

    jwtHelper: any;
    // Store authentication data
    // userProfile: any;
    // accessToken: string;
    // authenticated: boolean;

    redirectUrl: any;

    constructor(private router: Router, private jwtService: JwtService) {

        this.jwtHelper = new JwtHelperService();

        this.lock.on('authenticated', (authResult: any) => {

            if (authResult && authResult.accessToken && authResult.idToken) {
                this.setSession(authResult);
                console.log('NAVIGATING TO ANOTHER PAGE');
                this.router.navigate([this.redirectUrl]);


            }

        });

        this.lock.on('authorization_error', error => {
            console.log('Auth Failed', error);
        });
    }

    private setSession(authResult): void {

        console.log('setting session');
        console.log('here', this.redirectUrl);

        this.lock.getUserInfo(authResult.accessToken, (error, profile) => {
            if (error) {
                throw new Error(error);
            }
            this.setProfileToken(authResult.idToken);
            localStorage.setItem('token', authResult.idToken);
            localStorage.setItem('profile', JSON.stringify(profile));
        });
    }

    getLoggedInUser() {
        const user = localStorage.getItem('profile');
        return JSON.parse(user);
    }

    setProfileToken(idToken): void {

        this.jwtService.generate(idToken).subscribe((res) => {
            if (res) {
                localStorage.setItem('profile_token', res.token);
            }
        }, (err) => {
            console.log(err);
        });

    }

    login(redirectUrl: string = '/') {
        this.redirectUrl = redirectUrl;
        console.log('login', this.redirectUrl);
        this.lock.show();
    }

    logout() {
        localStorage.removeItem('profile');
        localStorage.removeItem('token');
        localStorage.removeItem('profile_token');
        this.router.navigate(['/']);
    }

    isAuthenticated() {
        const token = localStorage.getItem('token');
        return !this.jwtHelper.isTokenExpired(token);
    }

}

The auth service takes the state.url and adds it to a variable and then shows the lock. Within this service im listening to the authenticated event, setting a session and then redirecting to this redirect url that was set.

However auth0 already has its own redirectUrl that is currently pointed to the base url /. Once it goes there, the state this.redirectUrl becomes undefined.

How can i solve this problem.

Upvotes: 1

Views: 1579

Answers (2)

christian
christian

Reputation: 1705

I recently implemented custom redirect with the auth0-js library in an Angular app, using the WebAuth class. I followed the recommendations in the Auth0 docs: - https://auth0.com/docs/protocols/oauth2/redirect-users

Here is the flow that I use:

(before sending user to auth0 lock page)

  1. Generate a nonce (random string)
  2. store redirect path in a state object and stringify it
  3. Set nonce in localstorage
  4. invoke authorize method with nonce and stringified state: WebAuth.authorize({ nonce, state }) (this is what sends the user the auth0 lock page)
  5. when user login is processed, compare nonce from login result with nonce in localstorage
  6. if nonces match, parse stringified state from login result, extract redirect path, and redirect user
  7. clear nonce from localstorage

Upvotes: 0

Coding Morrison
Coding Morrison

Reputation: 423

Instead of altering your redirect_uri you can leverage a non-callback URL to fit your use case. This is often stored in the following ways:

  • For regular web apps, use a cookie or session
  • For a single-page app, use local storage in the browser
  • For a native app, use memory or local storage

From that point you can build out how you app responds to the redirect for your desired route. This is supported in Lock. I hope this helps you in your quest!

https://auth0.com/docs/users/guides/redirect-users-after-login

Upvotes: 1

Related Questions