Javascript 角度4:如何从拦截器显示重新登录对话框/模式

Javascript 角度4:如何从拦截器显示重新登录对话框/模式,javascript,angular,Javascript,Angular,问题陈述 我是Angular 4的新手,正在努力找出如何在令牌过期时让用户重新登录 让我们深入研究代码 我有一个响应拦截器,它检查响应代码是否有401错误 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(request).do( // success responses

问题陈述

我是Angular 4的新手,正在努力找出如何在令牌过期时让用户重新登录

让我们深入研究代码

我有一个
响应拦截器
,它检查响应代码是否有
401
错误

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

    return next.handle(request).do(
      // success responses
      (event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          // I do not want to do anything here... just pass
        }
      },
      // error responses
      (err: any) => {
        if (err instanceof HttpErrorResponse) {
          if (err.status === 401) {
            //here is where I need to show a modal
            //OH! STACKOVER-FLOW PLEASE BLESS ME
          }
        }
      });
  }
intercept(请求:HttpRequest,下一步:HttpHandler):
可观察{
返回next.handle(请求).do(
//成功回应
(事件:HttpEvent)=>{
if(HttpResponse的事件实例){
//我不想在这里做任何事…只是通过
}
},
//错误响应
(错误:任意)=>{
if(HttpErrorResponse的错误实例){
如果(错误状态===401){
//这里是我需要展示模态的地方
//哦!请保佑我
}
}
});
}
只是通知 应用程序太模块化,因为每个
组件
本身就是一个模块。例如:
登录组件
本身是一个模块,
注册
是另一个模块,它包含在根模块中,使用路由

所以,你能帮我找到解决这个谜题的最佳方法吗?

我用它来检查用户是否登录,我认为它的工作方式与你的方法相同。 无论如何,在您的canActivate服务中或在您的钩子中,我可以看到两种解决方案:

1) 如@Sajal所述——广播活动:

@Injectable()
export class YourService {

    heyStopRightThere: EventEmitter<boolean> = new EventEmitter();
    intercept(request: HttpRequest<any>, next: HttpHandler): 
      Observable<HttpEvent<any>> {

    ...
              if (err.status === 401) {
                   this.heyStopRightThere.emit();
              }
    ...
      }
}
@Injectable()
出口类服务{
heyStopRightThere:EventEmitter=新的EventEmitter();
拦截(请求:HttpRequest,下一步:HttpHandler):
可观察{
...
如果(错误状态===401){
this.heystoprighthare.emit();
}
...
}
}
然后在所有安全组件中

constructor(
        private _yrSvc: YourService
        ) {
    }

    showLoginDialog() {
        //enable component LoginDialog that embeded in
        // <loginDialog *ngIf="notLoggedIn"></loginDialog>
    }
    ngOnInit() {
        this._yrSvc.heyStopRightThere.subscribe(() =>
             showLoginDialog()
        );
    }
构造函数(
二等兵:你的服务
) {
}
showLoginDialog(){
//启用嵌入在中的组件LoginDialog
// 
}
恩戈尼尼特(){
这个._yrSvc.heystoprighthere.subscribe(()=>
showLoginDialog()
);
}
2) 使用param重定向到回调:

@Injectable()
export class YourService {
     constructor(private router: Router){}
     intercept(request: HttpRequest<any>, next: HttpHandler): 
       Observable<HttpEvent<any>> {
       ...
           if (err.status === 401) {
               this.router.navigate(['/login', {callback: location.href}]);
           }
       ...
     }
@Injectable()
出口类服务{
构造函数(专用路由器:路由器){}
拦截(请求:HttpRequest,下一步:HttpHandler):
可观察{
...
如果(错误状态===401){
this.router.navigate(['/login',{callback:location.href}]);
}
...
}
然后您可以在登录组件中绘制对话框,并在成功后重定向回“回调”。

我用它来检查用户是否登录,我认为它的工作方式与您的方法相同。 无论如何,在您的canActivate服务中或在您的钩子中,我可以看到两种解决方案:

1) 如@Sajal所述——广播活动:

@Injectable()
export class YourService {

    heyStopRightThere: EventEmitter<boolean> = new EventEmitter();
    intercept(request: HttpRequest<any>, next: HttpHandler): 
      Observable<HttpEvent<any>> {

    ...
              if (err.status === 401) {
                   this.heyStopRightThere.emit();
              }
    ...
      }
}
@Injectable()
出口类服务{
heyStopRightThere:EventEmitter=新的EventEmitter();
拦截(请求:HttpRequest,下一步:HttpHandler):
可观察{
...
如果(错误状态===401){
this.heystoprighthare.emit();
}
...
}
}
然后在所有安全组件中

constructor(
        private _yrSvc: YourService
        ) {
    }

    showLoginDialog() {
        //enable component LoginDialog that embeded in
        // <loginDialog *ngIf="notLoggedIn"></loginDialog>
    }
    ngOnInit() {
        this._yrSvc.heyStopRightThere.subscribe(() =>
             showLoginDialog()
        );
    }
构造函数(
二等兵:你的服务
) {
}
showLoginDialog(){
//启用嵌入在中的组件LoginDialog
// 
}
恩戈尼尼特(){
这个._yrSvc.heystoprighthere.subscribe(()=>
showLoginDialog()
);
}
2) 使用param重定向到回调:

@Injectable()
export class YourService {
     constructor(private router: Router){}
     intercept(request: HttpRequest<any>, next: HttpHandler): 
       Observable<HttpEvent<any>> {
       ...
           if (err.status === 401) {
               this.router.navigate(['/login', {callback: location.href}]);
           }
       ...
     }
@Injectable()
出口类服务{
构造函数(专用路由器:路由器){}
拦截(请求:HttpRequest,下一步:HttpHandler):
可观察{
...
如果(错误状态===401){
this.router.navigate(['/login',{callback:location.href}]);
}
...
}

然后,您的登录组件可以绘制对话框,并在成功后重定向回“回调”。

您可以向基本组件广播/发出消息,通过模板显示登录模式框——但这是一种方式。那么,为什么显示对话框或“截取”会有问题呢订阅是在服务内部吗?@sajal的评论是一种方式,如果您需要在令牌过期后登录应用程序的模式,
sajal
您的建议很好。
2opping
我想知道在这种情况下是否可以使用observable(我不知道怎么做,可能是在创建一个单独的服务来处理显示重新登录组件)
rahulSingh
我仍在寻找建议,以便我们评估最佳实践。要么我会得到一些答案,要么我自己在确认什么是好的(如果不是最好的话)后编写。你可以广播/发送消息到基本组件,通过模板显示登录模式框——但这是一种方法。那么,为什么要选择w dialog?或者你的“拦截”订阅是在服务内部?@sajal的评论是一种方式,如果你需要在令牌过期后登录到应用程序的模式
sajal
你的建议很好。
2opping
我想知道在这种情况下是否可以使用observable(我不知道怎么做,可能正在创建一个单独的服务来处理显示重新登录组件))
rahulSingh
我仍在寻找建议,以便我们可以评估最佳实践。要么我会得到一些答案,要么我自己在确认什么是好的(如果不是最好的)后编写