Angular Universal - Auth Guard 未决问题

Tod*_*vic 4 angular-universal angular ngrx-store auth-guard

我正在使用带有 Angular Material 的弹出登录,当我添加 Angular Universal 时,身份验证防护就是问题所在。如果某些路由受到身份验证保护,则页面只会开始挂起,并且永远不会结束。没有 Angular Universal 的行为是重新加载页面时它只是打开弹出窗口进行登录。

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(readonly auth: AuthService, public router: Router, private dialog: MatDialog, private store: Store<fromAuth.State>) {}

    /** Performs the user authentication prompting the user when neeed or resolving to the current authenticated user otherwise */

    public authenticate(action: loginAction = 'signIn') {
      return this.store.pipe(
        select(fromAuth.selectAuthState),
        take(1),
        switchMap(user => !user.user ? this.prompt(action) : of(user.user))
      ).toPromise();
    }

  public prompt(data: loginAction = 'signIn'): Promise<any> {

    return this.dialog.open<LogInComponent, loginAction>(LogInComponent, { data }).afterClosed().toPromise();
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // Gets the authorization mode when specified
    // const mode = route.queryParamMap.get('authMode') || 'signIn';
    // Prompts the user for authentication
     return this.authenticate()
      .then(user => !!user);
  }
}

Run Code Online (Sandbox Code Playgroud)

如果我直接访问 canActivate 内的 ngrx 存储,它可以工作,但我想使用 .toPromise()

我正在使用 httponly cookie,并且在每次重新加载时,Angular 都会向 nodejs 数据库发送 http 请求以获取用户数据。在所有其他路线上,它都按预期工作。

Jua*_*237 6

我认为我有一个简单实用的方法,只需在身份验证防护中进行验证,如果它是浏览器,则继续验证,如果它不只是继续,您不会遇到问题,因为 API 不会发送到服务器私人信息,因为没有提供令牌,然后在浏览器中重复整个过程,并为私有数据提供令牌。

身份验证守卫示例:

import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';

import { CanActivate, Router } from '@angular/router';

@Injectable({
    providedIn: 'root'
})
export class AuthGuard implements CanActivate {
    constructor(
        private router: Router,
        @Inject(PLATFORM_ID) private platformId: any
    ) {}

    canActivate(): boolean {
        var canContinue: boolean = false;

        if (isPlatformBrowser(this.platformId)) {
            // Browser
            // Verify here if the token exists
            canContinue = !!localStorage.getItem('token');

            if (!canContinue) this.router.navigate(['/error/401']);
        }
        if (isPlatformServer(this.platformId)) {
            // Server side
            canContinue = true;
        }

        return canContinue;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望这对你有用