为什么SwitchMap在角度拦截器(角度9)中不起作用 [英] why switchMap not working in Angular interceptor ( Angular 9 )

查看:0
本文介绍了为什么SwitchMap在角度拦截器(角度9)中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个拦截器来为我刷新令牌。但使用我检查的调试器,它根本不会进入SwitchMap,请求也不会再次发送它。 有人知道问题是从哪里来的吗?

    import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {Injectable, Injector} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import {catchError, switchMap, tap} from 'rxjs/operators';
import {ResponseModel} from '../Models/responseModel';
import {UserDataModel} from '../Models/UserDataModel';
import {RoleEnum} from '../Enums/RoleEnum';
import {AuthService} from '../../auth/auth.service';
import {AuthModel} from '../Models/authModel';
import {LoginType} from '../Enums/LoginType';
import {LoginResponseModel} from '../Models/LoginResponseModel';

@Injectable({providedIn: 'root'})
export class TokenInterceptor implements HttpInterceptor {
    httpSubject: BehaviorSubject<LoginResponseModel> = new BehaviorSubject<LoginResponseModel>(null);

    constructor(private injector: Injector) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        let modifiedReq;
        const userData: {
            username: string,
            access_token: string,
            refresh_token: string,
            role: RoleEnum,
            _tokenexpirationDate: string
        } = (JSON.parse(localStorage.getItem('userData')));
        if (userData.access_token !== null && !req.headers.has('X-Skip-Interceptor')) {
            modifiedReq = req.clone({
                headers: req.headers.set('access_token', `${userData.access_token}`),
            });
        } else {
            modifiedReq = req.clone({
                setHeaders: {
                    'Content-Type': 'application/json',
                    'Access-Control-Allow-Origin': '*'
                }
            });
        }
        return next.handle(modifiedReq).pipe(tap(res => {
            if (res instanceof HttpResponse) {
                const response = (<HttpResponse<ResponseModel<string>>> res).body;
                /*const userdata: {
                    username: string,
                    access_token: string,
                    refresh_token: string,
                    role: RoleEnum,
                    _tokenexpirationDate: string
                } = (JSON.parse(localStorage.getItem('userData')));*/
                if (!response.is_successfull) {
                    if (new Date() > new Date(userData._tokenexpirationDate)) {
                        this.refreshToken(req, next, userData.refresh_token, userData.username);
                    }
                }
            }
        }));
    }

    refreshToken(req: HttpRequest<any>, next: HttpHandler, refreshtoken: string, username: string) {
        this.httpSubject.next(null);
        const authService = this.injector.get(AuthService);
        const authmodel: AuthModel = {
            email_address: '', grant_type: LoginType.RefreshToken, password: '', phone_number: '', phone_number_countery_iso2_code: '',
            refresh_token: refreshtoken, username: ''
        };

        debugger;
        return authService.Signin(authmodel).pipe(
            switchMap(result => {
                debugger;
                if (result.is_successfull && result.response.access_token !== null) {
                    const expirationDate = new Date(new Date().getTime() + +result.response.expires_in * 60000);
                    const user = new UserDataModel(username, result.response.access_token, result.response.refresh_token
                        , result.response.role, expirationDate);
                    localStorage.setItem('userData', JSON.stringify(user));
                    this.httpSubject.next(result.response);
                    req = req.clone({
                        setHeaders: {
                            access_token: `${result.response.access_token}`
                        }
                    });
                    return next.handle(req);

                }

            }) , catchError(err => {
                console.log(err);
                return Observable;
            }));
    }
}

我还想说,如果我使用SUBSCRIBE而不是PIPE,SwitchMap,令牌将被刷新,只有请求不会从头开始重复。

推荐答案

您的代码应该是:-

   import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {Injectable, Injector} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import {catchError, switchMap, tap} from 'rxjs/operators';
import {ResponseModel} from '../Models/responseModel';
import {UserDataModel} from '../Models/UserDataModel';
import {RoleEnum} from '../Enums/RoleEnum';
import {AuthService} from '../../auth/auth.service';
import {AuthModel} from '../Models/authModel';
import {LoginType} from '../Enums/LoginType';
import {LoginResponseModel} from '../Models/LoginResponseModel';

@Injectable({providedIn: 'root'})
export class TokenInterceptor implements HttpInterceptor {
    httpSubject: BehaviorSubject<LoginResponseModel> = new BehaviorSubject<LoginResponseModel>(null);

    constructor(private injector: Injector) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        let modifiedReq;
        const userData: {
            username: string,
            access_token: string,
            refresh_token: string,
            role: RoleEnum,
            _tokenexpirationDate: string
        } = (JSON.parse(localStorage.getItem('userData')));
        if (userData.access_token !== null && !req.headers.has('X-Skip-Interceptor')) {
            modifiedReq = req.clone({
                headers: req.headers.set('access_token', `${userData.access_token}`),
            });
        } else {
            modifiedReq = req.clone({
                setHeaders: {
                    'Content-Type': 'application/json',
                    'Access-Control-Allow-Origin': '*'
                }
            });
        }
        return next.handle(modifiedReq).pipe(tap(res => {
            if (res instanceof HttpResponse) {
                const response = (<HttpResponse<ResponseModel<string>>> res).body;
                /*const userdata: {
                    username: string,
                    access_token: string,
                    refresh_token: string,
                    role: RoleEnum,
                    _tokenexpirationDate: string
                } = (JSON.parse(localStorage.getItem('userData')));*/
                if (!response.is_successfull) {
                    if (new Date() > new Date(userData._tokenexpirationDate)) {
                        this.refreshToken(req, next, userData.refresh_token, userData.username).then((request)=> {


                                   modifiedRequest = request.clone();
                                   throw "replay";
                     });
                    }
                }

        }),retryWhen(errors => errors);
    }

refreshToken(req: HttpRequest<any>, next: HttpHandler, refreshtoken: string, username: string) {
            this.httpSubject.next(null);
            const authService = this.injector.get(AuthService);
            const authmodel: AuthModel = {
                email_address: '', grant_type: LoginType.RefreshToken, password: '', phone_number: '', phone_number_countery_iso2_code: '',
                refresh_token: refreshtoken, username: ''
            };

            debugger;
            return await authService.Signin(authmodel).pipe(
                map(result => {
                    debugger;
                    if (result.is_successfull && result.response.access_token !== null) {
                        const expirationDate = new Date(new Date().getTime() + +result.response.expires_in * 60000);
                        const user = new UserDataModel(username, result.response.access_token, result.response.refresh_token
                            , result.response.role, expirationDate);
                        localStorage.setItem('userData', JSON.stringify(user));
                        this.httpSubject.next(result.response);
                        req = req.clone({
                            setHeaders: {
                                access_token: `${result.response.access_token}`
                            }
                        });
                        return req;

                    }

                }) , catchError(err => {
                    console.log(err);
                    return Observable;
                })).toPromise();
        }
    }

原因:-Tap不订阅您正在返回的内心可察觉。Mergeap就是这么做的。应使用正确的运算符完成流合并。

这篇关于为什么SwitchMap在角度拦截器(角度9)中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆