当令牌在角度4中过期时如何重定向到注销

Posted

技术标签:

【中文标题】当令牌在角度4中过期时如何重定向到注销【英文标题】:How to redirect to logout when token expired in angular 4 【发布时间】:2018-10-20 08:39:06 【问题描述】:

我有一个 Angular 4 应用程序。我在那里使用 JWT 令牌进行身份验证。一切正常。但是我给 JWT 令牌的令牌过期时间是 1 小时。一旦令牌在服务器端过期,我想将用户从前端应用程序中注销。在节点后端,我使用快速中间件通过检查所有请求是否包含有效令牌来处理此问题。有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

您可以使用 Http 拦截器。如果有任何未经授权的 401 响应。假设您正在发送带有标头中令牌的 http 请求。您的服务器端代码检查您的令牌,最后发现,令牌无效/过期返回 401 代码,您可以将用户重定向到登录页面。并且手动传递令牌并检查所有授权/未授权的http请求是非常重复的工作,您可以通过拦截器作为http请求的委托来完成这项常见任务。查看代码示例,您将获得解决方案。

AppHttpInterceptor.ts

import  Injectable  from "@angular/core";
import 
    HttpInterceptor,
    HttpRequest,
    HttpResponse,
    HttpErrorResponse,
    HttpHandler,
    HttpEvent
 from '@angular/common/http';

import  Observable  from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import  Http, Response, RequestOptions, Headers  from '@angular/http';
import  Router  from '@angular/router'


@Injectable()
export class AppHttpInterceptor implements HttpInterceptor 
    constructor(private router: Router)

    
    headers = new Headers(
        'Content-Type': 'application/json',
        'Token': localStorage.getItem("Token")
    );
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 

        console.log("intercepted request ... ");

        // Clone the request to add the new header.
        const authReq = req.clone( headers: req.headers.set("Token", localStorage.getItem("Token")) );

        console.log("Sending request with new header now ...");

        //send the newly created request
        return next.handle(authReq)
            .catch(err => 
                // onError
                console.log(err);
                if (err instanceof HttpErrorResponse) 
                    console.log(err.status);
                    console.log(err.statusText);
                    if (err.status === 401) 
                        window.location.href = "/login";
                    
                
                return Observable.throw(err);
            ) as any;
    

app.module.ts

import  BrowserModule  from '@angular/platform-browser';
import  NgModule  from '@angular/core';
import  HttpModule  from '@angular/http';
import  HttpClient  from "@angular/common/http";
import  FormsModule  from '@angular/forms';
import  ToasterModule, ToasterService  from "angular2-toaster";
import  BrowserAnimationsModule  from '@angular/platform-browser /animations';
import  RouterModule  from '@angular/router';
import  ReactiveFormsModule  from '@angular/forms';
import  HttpClientModule,HTTP_INTERCEPTORS from '@angular/common/http';
import AppHttpInterceptor from './Common/AuthInterceptor';
import  AppRoutes  from '../app/Common/Routes';
import  AppComponent  from './app.component';

@NgModule(
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule, HttpModule,HttpClientModule, ReactiveFormsModule, FormsModule, BrowserAnimationsModule, RouterModule.forRoot(AppRoutes)
  ],
 providers: [
 
   provide: HTTP_INTERCEPTORS,
   useClass: AppHttpInterceptor,
   multi: true
 
],
bootstrap: [AppComponent]
)
export class AppModule  
  constructor(private httpClient: HttpClient)
    this.httpClient.get("https://jsonplaceholder.typicode.com/users").subscribe(
  success => 
    console.log("Successfully Completed");
    console.log(success);
  
  );
 

【讨论】:

这对我没有任何作用。我认为这不会被触发。你确定这个示例代码是正确的。我需要做更多的事情吗? 我已经在我的项目中实现了,它工作正常。假设您的项目有 200 多个 api。这些是由多个类和方法分隔的 api。您将如何识别任何有效或无效的请求?通过 ngOnInit() 你可以检查它,但它只用于组件加载时间,发送任何 post 请求后怎么样。 如何检测http请求是否有效?假设我想保存一个客户,在发送请求后,服务器给了我 401 错误,你将如何通知用户你的请求无效。是的,您可以通过所有方法中的错误响应来做到这一点,但请记住您需要为所有操作实施的这项常见工作,这是压倒性的,拦截器将允许您执行此常见任务。请阅读 angular4 中的 http 拦截器 一件事是重要的拦截器仅使用 HttpClient 而不是 Http 触发 检查我的 app.module.ts 构造函数并使用 http 请求调用,然后你就明白它的工作/不。【参考方案2】:

您可以检查令牌是否过期,作为响应,您可以重定向到登录页面 将令牌存储在本地存储中 例如

 yourmthod(parametr) 
        this.token = localStorage.getItem("token");
        this.headers = new Headers();
        this.headers.delete(this.token);
        this.headers.append("Authorization", this.token);
        return this._http.post(Constants.SERVER_URL + 'your method', headers: this.headers);
    

所以它会响应 401 错误,您可以通过重定向到您的登录页面来处理此问题

如有任何疑问,您可以在 cmets 中提出问题,以便我可以帮助您

你也可以在你的方法中使用 if-else

你可以在app.component.ts中用onIt()方法写代码

ngOnInit(): void 
        let token = localStorage.getItem("token");
        if (token) 
            this.isTokenAvaialable = true;
            this.http.get(Constants.SERVER_URL + 'your mthod to validate token' + token).subscribe(data => 
                if (data == true) 
                    if (window.location.pathname == "") 
                        this.router.navigate(['/home', outlets: 'r2': ['dashboard']]);
                    
                 else if (data == false) 

                    this.logout('Server restarted.Please login again!!');
                 else 

                    this.logout('Session expired.Please login again.!!');
                

            , (err: HttpErrorResponse) => 
                this.toastr.warning('Server restarted.Please login again!!', 'Alert');
                localStorage.removeItem("token");
                this.isTokenAvaialable = false;
                this.logout('Server restarted.Please login again!!');
            );
         else 
            this.isTokenAvaialable = false;
            this.router.navigate(['']);
            localStorage.removeItem("token");
            this.isTokenAvaialable = false;
        
    

【讨论】:

你也可以使用 HttpIntercepter ,belo sn-pCode import Injectable from '@angular/core';从“@angular/common/http”导入 HttpEvent、HttpInterceptor、HttpHandler、HttpRequest;从 'rxjs/Rx' 导入 Observable; @Injectable() 导出类 deckAuthInterceptor 实现 HttpInterceptor intercept(req: HttpRequest, next: HttpHandler): Observable> let token = localStorage.getItem("token"); const authReq = req.clone( headers: req.headers.set('Authorization', token) );返回下一个.handle(authReq); 【参考方案3】:

angular2-jwt 中有 tokenNotExpired 方法,您可以使用它来检查令牌过期时间

试试这个

  authHttpGet(URL: string): Observable<any> 
    if (!tokenNotExpired('id_token')) 
      this._route.navigate(['login']);
    
  

【讨论】:

以上是关于当令牌在角度4中过期时如何重定向到注销的主要内容,如果未能解决你的问题,请参考以下文章

如果令牌过期,如何在 apollo 客户端中重定向或导航

在颤动中按下注销按钮后如何重定向到登录页面

Java Web 应用程序中的会话过期时如何重定向到登录页面?

注销后如何重定向到主页?

如果会话过期,如果没有活动并重定向登录页面,则烧瓶注销

如何配置在Django中注销后重定向到哪里?