如何解决使用Angular 6查看未授权页面的问题?

问题描述 投票:0回答:1

我有一个用Angular 6编写的应用程序。我在此应用程序中使用了各种API调用。实际上,当我收到401响应时,可以正确地重定向到登录页面。但是,当我想随时登录此应用程序时,首先会看到一个仪表板屏幕,可以将其视为登录屏幕。然后它将我重定向到登录页面。如何防止此页面出现?我搜索了许多资源,但找不到解决方案。如果需要,我可以分享有关代码的部分。您认为什么可能是问题的根源?

angular6
1个回答
0
投票

跟随StackBlitz example

您可以创建一个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

© www.soinside.com 2019 - 2024. All rights reserved.