无需使用本地存储或cookie的角度身份验证防护

时间:2018-12-13 11:31:37

标签: angular

我有一个有角度的项目,其登录由拦截器控制。具有服务器的浏览器的身份验证和会话维护已在此处编写。我想将登录名引入为auth Guard,并将重定向逻辑移至Guard服务。

我要这样做的原因是:每当我第一次在浏览器中打开任何页面时,该页面UI就会显示半秒钟,然后重定向到登录页面。实际上,即使不进行身份验证,我也不想显示该页面半秒钟。因此,我计划将auth作为所有模块的防护。

我查看了互联网上的答案,发现其中一些使用了一些变量存储,该变量存储在登录,注销和身份验证保护之间共享,并且身份验证保护正在检查该变量,并根据其值进行重定向。我不想使用任何额外的变量。我正在寻找与浏览器会话进行通信的任何选项,因为浏览器已经在维护它。

我的拦截器如下:

export class InterceptorService implements HttpInterceptor {

  constructor(private router: Router) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const xhr = request.clone({
            headers: request.headers.set('X-Requested-With', 'XMLHttpRequest')
        });
        //return next.handle(xhr);
        return next.handle(xhr).pipe(tap((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // do stuff with response if you want
            }
        }, (err: any) => {
            if (err instanceof HttpErrorResponse) {
                if (err.status === 401) {
                    this.router.navigateByUrl('login');
                }
            }
        }));
    }

}

我正在主页上进行一次get呼叫,默认路由指向该页面。

任何指针都会有所帮助。预先感谢!

1 个答案:

答案 0 :(得分:0)

Guard是可以取消导航,从而不会显示页面的东西。因此,基本上是的,如果您未对用户进行身份验证,则可以在其中进行检查并防止导航。检查用户是否通过身份验证的方式取决于身份验证类型。

例如,如果您使用cookie身份验证,则好的做法是让端点返回当前用户数据。因此,如果用户未通过身份验证,authGuard可以调用此端点,然后检查其结果以取消导航。

@Injectable({
  providedIn: 'root',
})
export class AuthGuard implements CanActivate {
  constructor(private _httpClient: HttpClient, private _router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
      return this._httpClient.get('<current user info endpoint>', {withCredentials:true}) // makes a call with a cookie
        .pipe(
           map(response => response.status !== 401)
        )
        .toPromise()
        .then(canActivate => {
          if(!canActivate) {
            this._router.navigate(['/login']);
          }
        });
  }
}

请注意,对于每个导航都进行API调用是不好的。最好缓存身份验证数据。例如,您可以在服务或localStorage中设置状态。