Angular2 / 4 http拦截器刷新令牌和重复的初始失败请求

时间:2017-08-10 06:26:42

标签: angular angular2-services

您好我面临一个自定义http类的问题,它扩展了我创建的默认http。我在获取401错误后应用刷新令牌时遇到问题,并且未使用新刷新令牌创建失败的请求。

使用刷新令牌,我将调用其他api来获取新的access_token并更新参数

请参阅下面的代码,以便在我在请求段中获取未经授权的HTTP 401错误时更加了解我正在做的事情。

import { Router } from '@angular/router';
import { Injectable } from "@angular/core";
import { ConnectionBackend, RequestOptions, Request, RequestOptionsArgs, Response, Http, Headers } from "@angular/http";
import { Observable } from "rxjs/Rx";
import { appConfig } from "./app.config";
import 'rxjs/add/operator/toPromise';

@Injectable()
export class InterceptedHttp extends Http {

    headers = new Headers();
    options1 = new RequestOptions;
    requestURLs: any;
    counter: any = 0;
    pendingRequests: any = [];

    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private router: Router) {
        super(backend, defaultOptions);
    }

    // request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    //     return this.intercept(super.request(url, this.getRequestOptionArgs(options)));
    // }

    callthisReq(url, options) {

    }

    request(url: string | Request | any, options?: RequestOptionsArgs): Observable<Response> {
        console.log(window.location.href);
        let str: string = window.location.href;
        let output = str.split('#');
        console.log(output[1]);
        return super.request(url, options).catch(error => {
            if (error.status === 401) {
                this.pendingRequests.push(url);
                console.log(url);
                // It the token has been expired trigger a refresh and after that continue the original request again with updated authorization headers.
                let ref = JSON.parse(localStorage.getItem('currentUser')).refresh_token;
                this.refreshToken(ref)
                    .then(result => {
                        console.log(result);
                        this.headers.delete('Authorization');
                        this.headers.delete('Content-Type');
                        this.headers.append('Authorization', result.token_type + result.access_token);
                        this.headers.append('Content-Type', 'application/json');
                        localStorage.setItem('currentUser', JSON.stringify(result));
                        this.options1 = new RequestOptions({ headers: this.headers });
                        // this.requestRefreshUrl(url.url, this.options1)
                        //     .then(result => {
                        //         console.log(result);
                        //         // return result;
                        // });
                        for (let i = 0; i < this.pendingRequests.length; i++) {
                            // return this.request(this.pendingRequests[i].url,this.options1);
                            // this.request(this.pendingRequests[i].url, )
                            this.requestRefreshUrl(this.pendingRequests[i].url,this.options1)
                                .then(result => {
                                    console.log(result);
                                    // return result;
                                });
                        }
                    })
                    .catch(error => console.log(error));
            } else {
                return Observable.throw(error);
            }
        });
    }




    // request(url: string | Request | any, options?: RequestOptionsArgs): Observable<Response> {
    //     console.log(url);
    //     return super.request(url, this.getRequestOptionArgs(options))
    //         .catch((error) => {
    //             //if got authorization error - try to update access token
    //             console.log(error);
    //             if (error.status = 401) {
    //                 this.pendingRequests.push(url);
    //                 let ref = JSON.parse(localStorage.getItem('currentUser')).refresh_token;
    //                 return this.refreshToken(ref)
    //                     .flatMap((result: any) => {
    //                         if (result) {// got new access token - retry request
    //                             console.log(result);
    //                             // this.headers.delete('Authorization');
    //                             // this.headers.delete('Content-Type');
    //                             this.headers.append('Authorization', result.token_type + result.access_token);
    //                             this.headers.append('Content-Type', 'application/json');
    //                             // this.options1 = new RequestOptions({ headers: this.headers });
    //                             url.headers.set('Authorization', this.headers);
    //                             console.log(this.pendingRequests);
    //                             for (let i = 0; i < this.pendingRequests.length; i++) {
    //                                 console.log(this.pendingRequests[i]);
    //                                 this.headers.append('Authorization', result.token_type + result.access_token);
    //                                 this.headers.append('Content-Type', 'application/json');
    //                                 this.pendingRequests.url.headers.set('Authorization', this.headers);
    //                                 this.options1 = new RequestOptions({ headers: this.headers });
    //                                 this.request(this.pendingRequests[i].url, this.options1)
    //                                     .map((response: Response) => response.json())
    //                                     .subscribe(responseData => {
    //                                         console.log(responseData);
    //                                     })
    //                             }

    //                             // return this.request(url, options);
    //                         }
    //                         //otherwise - throw error
    //                         else {
    //                             return Observable.throw(new Error('Can\'t refresh the token'));
    //                         }

    //                     })
    //             }
    //             else {
    //                 Observable.throw(error);
    //             }
    //         })
    // }

    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        url = this.updateUrl(url);
        return this.intercept(super.get(url, this.getRequestOptionArgs(options)));
    }

    post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
        url = this.updateUrl(url);
        return this.intercept(super.post(url, body, this.getRequestOptionArgs(options)));
    }

    put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
        url = this.updateUrl(url);
        return this.intercept(super.put(url, body, this.getRequestOptionArgs(options)));
    }

    delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
        url = this.updateUrl(url);
        return this.intercept(super.delete(url, this.getRequestOptionArgs(options)));
    }

    private updateUrl(req: string) {
        this.requestURLs = req;
        return appConfig.devapiUrl + req;
    }

    // private refreshtoken(token: string) {
    //     return appConfig.devapiUrl + req;
    // }    
    getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
        if (options == null) {
            options = new RequestOptions();
        }
        if (options.headers == null) {
            options.headers = new Headers();
        }
        // options.headers.append('Content-Type', 'application/json');

        let currentUser = JSON.parse(localStorage.getItem('currentUser'));
        if (currentUser) {
            console.log(currentUser.access_token);
            options.headers.append('Authorization', currentUser.token_type + currentUser.access_token);
            options.headers.append('Content-Type', 'application/json');
        }

        return options;
    }

    intercept(observable: Observable<Response>): Observable<Response> {
        return observable.catch((err, source) => {
            if (err.status == 401) {
                console.log("this is 401 error,call refreshtoken to get and update the token");
                // console.log(JSON.parse(localStorage.getItem('currentUser')).refresh_token);
                return Observable.empty();
            } else {
                return Observable.throw(err);
            }
        });

    }

    // protected intercept(observable: Observable<Response>): Observable<Response> {
    //     return observable.catch((err, source: any) => {
    //         if (err.status == 401) {
    //             console.log("Unauthorised need to refresh token");
    //             let ref = JSON.parse(localStorage.getItem('currentUser')).refresh_token;
    //             console.log(ref);
    //             console.log(err.url);
    //             console.log(source);
    //             // console.log(this.requestURLs);
    //             this.pendingRequests.push(err.url);
    //             this.options1 = new RequestOptions({ headers: this.headers });

    //             // // console.log(source.operator.caught.source);
    //             this.refreshToken(ref)
    //                 .flatMap(data => {
    //                     return observable.retry(this.pendingRequests.length);
    //                 })
    //             // return this.refreshToken(ref).flatMapTo(source);

    //         } else {
    //             return Observable.throw(err);
    //         }
    //     });
    // }
    private extractData(res: Response) {
        let body = res.json();
        return body || [];
    }
    private handleError(error: any) {
        // In a real world app, we might use a remote logging infrastructure
        // We'd also dig deeper into the error to get a better message
        let errMsg = (error.message) ? error.message :
            error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }

    protected refreshToken(refreshtoken: string, options?: RequestOptionsArgs): Promise<any> {
        {
            console.log(this.counter);

            localStorage.removeItem('currentUser');
            if (this.counter == 0) {
                console.log("Iam here1");
                this.headers.append('Authorization', 'Basic Yml0N3BheWFwcDoxMjM0NTY=');
                this.headers.append('Content-Type', 'application/x-www-form-urlencoded');
                this.options1 = new RequestOptions({ headers: this.headers });

                var url = this.updateUrl('/oauth/token?grant_type=refresh_token&refresh_token=' + refreshtoken)
                this.counter++;
                return super.post(url, {}, this.options1)
                    .toPromise()
                    .then(this.extractData)
                    .catch(this.handleError);
            }
            if (this.counter > 0) {
                console.log("Iam here2");
                let currentUser = JSON.parse(localStorage.getItem('currentUser'));
                console.log(currentUser);
                return currentUser;
            }
        }
    }

    protected requestRefreshUrl(url: string, options?: RequestOptionsArgs): Promise<any> {
        return super.request(url, this.options1)
            .toPromise()
            .then(this.extractData)
            .catch(this.handleError);
    }



}

在请求段中,我正在尝试刷新令牌功能。请提出建议。

0 个答案:

没有答案