Angular工程:当用户token过期后,返回登录界面

问题

Angular工程,当用户一段时间没有操作,后端会让token过期,这时应该返回登录界面。

实现原理

通过Http拦截器来实现这个功能。
让后端API在token过期后返回一个固定的状态,本例是response.body.code === ‘00191’。前端拦截Http调用,检查response,如果发现token过期,就发射一个login事件(通过事件与AppComponent#createLoginPage解耦),通过setTimeout延迟发射是为了保证这个http请求的回调函数得到调用之后再调整到登录界面。如果浏览器的事件处理本身就是异步的(事件驱动的机制应该如此),那么setTimeout就是多余的,放在这里也没有坏处。

DynamicCreateService见我的另一篇博客:angular动态创建组件的服务代码

本例也演示了如何在每个请求上面加上头部Authorization,向后端API发送用户token。

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpResponse,
  HttpHandler,
  HttpEvent,
  HttpErrorResponse
} from '@angular/common/http';
import { Subscription } from 'rxjs';
import { tap } from 'rxjs/operators';

import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

@Injectable()
export class HttpConfigInterceptor implements HttpInterceptor {
  constructor() { }
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token: string = sessionStorage.getItem('userToken');

    if (token) {
      request = request.clone({ headers: request.headers.set('Authorization', 'Bearer' + token) });

      return next.handle(request).pipe(
        tap((event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            if (event.body.code === '00191') {
              sessionStorage.clear();
              // go to log in page
              setTimeout(() => {
                const event2 = new CustomEvent('login', { detail: {} });
                window.dispatchEvent(event2);
              }, 0);
            }
          }
        }));
    }

    return next.handle(request);
  }
}
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit, AfterViewInit {
  @ViewChild('viewContainer', { read: ViewContainerRef }) container: ViewContainerRef;
  componentRef: ComponentRef<any>;

  constructor(
    private dcs: DynamicCreateService,
    private http: HttpClient,
    // ...
  ) {
  }

  ngOnInit(): void {
    window.addEventListener('resize', this.onWindowResize.bind(this));
    window.addEventListener('login', () => {
      this.createLoginPage();
    });
  }

  ngAfterViewInit(): void {
    if (sessionStorage.getItem('userToken')) {
      this.createHomePage();
    } else {
      this.createLoginPage();
    }
    document.oncontextmenu = () => false;
  }

  createLoginPage() {
    this.componentRef = this.dcs.createComponent(this.container, LoginComponent);
    (this.componentRef.instance as LoginComponent).login.subscribe(() => this.createHomePage());
  }
  
  // ...
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值