我有一个有角度的项目,其登录由拦截器控制。具有服务器的浏览器的身份验证和会话维护已在此处编写。我想将登录名引入为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呼叫,默认路由指向该页面。
任何指针都会有所帮助。预先感谢!
答案 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中设置状态。