首页 > 解决方案 > Show login modal on unauthorized response angular 7

问题描述

I need to show a login modal every time the server returns a http unauthorized status (401), and in that case, stop the page loading... for example, I'm logged in but trying to access an protected resource that only admin users can do it.. so in that case I would like to show an modal with login and password to the user. It could be on navigating to a protected route or on delete event for example.

I tried to do it in an ApiInterceptor:

@Injectable({providedIn: 'root'})
export class ApiInterceptor implements HttpInterceptor {

  constructor(
    ...
  ) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    req = req.clone({ url: environment.baseUrl + req.url });

    if (this.authService.validToken) {
      req = req.clone({ headers: req.headers.set('Authorization', `Bearer ${this.authService.validToken}`) });
    }

    if (!req.headers.has('Content-Type')) {
      req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
    }

    return next.handle(req).pipe(catchError(resp => this.handleError(resp)));

  }

  private handleError(httpError: HttpErrorResponse) {
      if (httpError.status === this.UNAUTHORIZED) {
        // opening login modal here, but can't stop the request to prevent user to se unauthorized data, and after login, how can I redirect user to the same resource he tried to access?
      }
      return throwError(httpError);
  }

}

Need help here, if someone have an idea in how to do it will be appreciated!

标签: javascriptangularangular7

解决方案


ApiInterceptor看起来像是为请求添加不记名令牌。我将其称为TokenInterceptor或类似的,并创建一个新的来处理未经授权的请求。

我会创建一个新的拦截器并调用它UnauthorisedRequestInterceptor。与此类似的东西:

@Injectable({ providedIn: 'root' })
export class UnauthorisedRequestInterceptor implements HttpInterceptor {

    constructor(private router: Router) { }

    intercept(
        req: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<any>> {
        return next.handle(req).pipe(
            map(event => {
                return event;
            }),
            catchError((error: HttpErrorResponse) => {
                if (error.status === 401) {
                    this.router.navigate(['/auth/login']);
                }
                return throwError(error);
            })
        );
    }
}

这将拦截每个 http 请求,如果返回的状态为 401,它会将您重定向到您的登录页面。

然后将其添加到您的提供者列表中app.module.ts

providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: UnauthorisedRequestInterceptor,
      multi: true
    }
  ]

至于将用户重定向到受保护的路由,这应该在您的身份验证守卫中完成。


推荐阅读