我有一个用Angular 6
编写的应用程序。我在此应用程序中使用了各种API
调用。实际上,当我收到401
响应时,可以正确地重定向到登录页面。但是,当我想随时登录此应用程序时,首先会看到一个仪表板屏幕,可以将其视为登录屏幕。然后它将我重定向到登录页面。如何防止此页面出现?我搜索了许多资源,但找不到解决方案。如果需要,我可以分享有关代码的部分。您认为什么可能是问题的根源?
您可以创建一个HttpInterceptor
。这负责拦截离开应用程序的所有请求,并可以处理返回到应用程序的任何响应。下面是一个简单的示例,如果任何请求返回401状态,则将用户重定向到登录:
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { Router } from '@angular/router'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private router: Router) {} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(request).pipe(catchError(error => { if (error instanceof HttpErrorResponse) { if (error.status === 401) { // 401 unauthorize HttpErrorResponse this.router.navigateByUrl('/login'); return throwError(error); } } return throwError(error); })) } }
让我们看一下这里发生的事情。
request
包含有关我们的HTTP请求的所有信息。您可以在此处执行所需的任何验证(确保设置了令牌和标头,验证了请求正文等)。
next.handle(request)
是表示我们的HTTP响应的Observable。我们可以使用.pipe
访问此Observable。如果服务器以任何错误代码响应,则此Observable会引发错误,因此我们使用.pipe(catchError)
处理它。这接受使用HttpErrorResponse作为参数的回调函数。在这里,您可以检查HttpErrorResponse的状态是否为401,然后将用户路由到登录页面。
catchError
的回调函数必须返回一个Observable,因此我们使用throwError
将错误重新包装在Observable中。
要将此拦截器合并到整个应用程序中,需要按如下所示在AppModule
中提供此拦截器:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { HelloComponent } from './hello.component'; import { AuthService } from './auth.service'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthInterceptor } from './auth-interceptor'; import { Router, RouterModule } from '@angular/router'; @NgModule({ imports: [ BrowserModule, FormsModule, RouterModule ], declarations: [ AppComponent, HelloComponent ], bootstrap: [ AppComponent ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, deps: [Router] } ] }) export class AppModule { }
注意我们如何在HttpInterceptor提供程序声明的
Router
数组下列出deps
,以便AuthInterceptor中注入的Router
可以按预期工作。
关于短暂显示DashboardComponent
,然后重新路由到LoginComponent
,您可以将所有DashboardComponent
HTML包装在中,然后使用*ngIf
查看用户是否已通过身份验证,然后再显示组件。您希望在构造函数或ngOnInit()
方法中执行此操作,因为这些操作是在将HTML放到屏幕上之前运行的。
希望这会有所帮助。以下是有助于解决此问题的文章:
Angular Authentication: Using the Http Client and Http Interceptors
Handle http responses with HttpInterceptor and Toastr in Angular