0

目标:如果用户导航到受保护的链接,他们应该被给予 auth0 锁定弹出窗口以登录并被重定向到他们的预期目的地。

我有一个受保护的路由/reports,它通过 authguard 服务受到保护。

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;
    }
}

守卫尝试通过 state.url 登录(这是用户在被提示登录之前打算去的地方)。

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);
    }

}

auth 服务获取 state.url 并将其添加到变量中,然后显示锁。在此服务中,我正在侦听经过身份验证的事件,设置会话,然后重定向到设置的此重定向 url。

但是 auth0 已经有自己的 redirectUrl ,它当前指向基本 url /。一旦它到达那里,状态 this.redirectUrl 变得未定义。

我怎么解决这个问题。

4

2 回答 2

0

我最近auth0-js使用该类在 Angular 应用程序中使用库实现了自定义重定向WebAuth。我遵循了 Auth0 文档中的建议:- https://auth0.com/docs/protocols/oauth2/redirect-users

这是我使用的流程:

(在将用户发送到 auth0 锁定页面之前)

  1. 生成一个随机数(随机字符串)
  2. 将重定向路径存储在state对象中并将其字符串化
  3. 在本地存储中设置随机数
  4. 调用具有 nonce 和字符串化状态的授权方法:(WebAuth.authorize({ nonce, state })这是向用户发送 auth0 锁定页面的原因)
  5. 处理用户登录时,将登录结果中的 nonce 与 localstorage 中的 nonce 进行比较
  6. 如果 nonces 匹配,则从登录结果中解析字符串化状态,提取重定向路径,并重定向用户
  7. 从本地存储中清除随机数
于 2019-11-04T03:41:19.910 回答
0

您可以利用非回调 URL 来适应您的用例,而不是更改您的 redirect_uri。这通常以以下方式存储:

  • 对于常规网络应用,使用 cookie 或会话
  • 对于单页应用,在浏览器中使用本地存储
  • 对于原生应用,使用内存或本地存储

从那时起,您可以构建您的应用程序如何响应您所需路线的重定向。这在 Lock 中受支持。我希望这对你的追求有所帮助!

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

于 2019-06-25T21:04:21.040 回答