课程里面可以加上token失效后,token刷新功能吗

来源:1-1 课程导学

天空中的天空的空

2019-06-10

    我最近正在做这块,但是http我大概写了个拦截器。但是不能对error进行有效的拦截,请老师对这块重点讲一下。
写回答

1回答

接灰的电子产品

2019-06-10

import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler } from "@angular/common/http";
import { BehaviorSubject, Observable } from "rxjs";
import { catchError, switchMap, filter, take } from "rxjs/operators";
 
@Injectable({
    providedIn: 'root'
})
export class RefreshTokenInterceptor implements HttpInterceptor {
 
    private refreshTokenInProgress: boolean = false;
 
    private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(
        null
    );
 
    constructor(public accountService: AccountService) {}
 
    intercept(request: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
 
        // 首先检查 token 是否过期
        // 如果没有过期,在 Request Headere 添加鉴权头 addAuthenticationToken();
 
        // 如果过期
        if (tokenHasExpired()) {
 
            if (this.refreshTokenInProgress) {
 
                // 如果 refreshTokenInProgress 为真, 我们需要等到 refreshTokenSubject 有非 null 值
                // 此时才意味着新的 token 已经准备好了,我们可以重试请求
                return this.refreshTokenSubject.pipe(
                    filter(result => result !== null),
                    take(1),
                    switchMap(() => next.handle(this.addAuthenticationToken(request)))
                );
 
            } else {
 
                this.refreshTokenInProgress = true;
 
                // 设置 refreshTokenSubject 为 null,这样后继的请求会等待新 token 的生成
                this.refreshTokenSubject.next(null);
 
                return this.accountService.renewToken()
                        .pipe(                        
                            switchMap(t => {
 
                                this.accountService.saveToken(t);
                                let token = this.accountService.getAccessToken();
 
                                this.refreshTokenInProgress = false; // 设置 refreshTokenInProgress 为 False
                                this.refreshTokenSubject.next(token); // 发射新 token 
 
                                var newReq = this.setToken(req, token);
                                return next.handle(newReq);
 
                            }),
                            catchError((err) => {
 
                                this.refreshTokenInProgress = false;
                                return Observable.throw(err);
 
                            })
                        );
            }
 
        } else {
 
            return this.addAuthenticationToken(request);
 
        }
 
    }
 
    addAuthenticationToken(request) {
        // 从本地取 token
        const accessToken = this.accountService.getAccessToken();
 
        // 如果 access token 是 null,说明用户没有登录
        // 直接返回原来的请求
        if (!accessToken) {
            return request;
        }
 
        // clone 请求, 添加 header
        return request.clone({
            setHeaders: {
                Authorization: accessToken
            }
        });
    }
 
}


0
2
天空中的天空的空
非常感谢!
2019-10-25
共2条回复

Angular 开发拼多多webapp 从基础到项目实战

高仿拼多多WebApp,带你在实战环境中学习Angular

1322 学习 · 451 问题

查看课程