Angular Как использовать перехватчик для обновления токена авторизации

У меня есть два токена, token_a длится очень долго. token_a используется для генерации token_b. token_b длится недолго. token_b используется для большинства вызовов API. Тем не менее, мне нужен автоматический способ регенерировать этот токен, когда он истек.

Я пытаюсь использовать для этого перехватчик, который добавит заголовок авторизации ко всем http-вызовам. Однако, если он находит, что токен истек, он пытается восстановить токен и установить заголовок.

auth.interceptor.ts

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/observable';
import 'rxjs/add/operator/do';

import { AuthService } from './../services/auth/auth.service';
import { JwtService } from './../services/jwt/jwt.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(private auth: AuthService, private jwt: JwtService) {
        console.log('Interceptor Init');
    }

    setHeader(req) {

        const authToken = this.auth.getProfileToken();

        const authReq = req.clone({
            headers: req.headers.set('Authorization', 'Bearer ' + authToken)
        });

        return authReq;
    }

    intercept(req: HttpRequest<any>, next: HttpHandler) {

        console.log('Intercepting');
        const InterceptorSkipHeader = 'X-Skip-Interceptor';
        console.log(req);

        if (req.headers.has(InterceptorSkipHeader)) {
            console.log('Skipping');
            const headers = req.headers.delete(InterceptorSkipHeader);
            return next.handle(req.clone({ headers }));
        }

        if (this.auth.hasProfileToken() && this.auth.isProfileTokenExpired()) {
            console.log('Intercepter Refreshing Token Here');
            const t = localStorage.getItem('token');

            this.jwt.generate(t).subscribe((res) => {
                if (res) {
                    localStorage.setItem('profile_token', res.token);
                    const auth_req = this.setHeader(req);
                    console.log('here1');
                    return next.handle(auth_req);
                }
            }, (err) => {
                console.log(err);
            });
        }

        console.log('end');

        const authReq = this.setHeader(req);

        console.log('end interceptor');
        return next.handle(authReq);

    }

}

Тем не менее, я заметил, что мои вызовы API, такие как следующий, который запускается при нажатии кнопки и получает данные, используя источник данных из внутреннего ресурса. Кажется, его вызывают до того, как перехватчик завершит восстановление нового токена и установит заголовок.

jobs.datasource.ts

this.jobService.all(params).pipe(
    catchError(() => of([])),
    finalize(() => {
        this.page = params.offset / 15 + 1;
        this.offset = params.offset;
    })
)
    .subscribe((jobs) => {
        console.log('here 2');
        console.log(jobs);
        this.loadingSubject.next(false);
        this.jobsSubject.next(jobs.data);

        (jobs.next) ? this.nextSubject.next(true) : this.nextSubject.next(false);
    });

Я только это происходит, потому что я добавил 2 отдельных журнала консоли в каждом файле. console.log("here 2") в jobs.datasource вызывается раньше console.log("here 1") в аут.интерцепторе.

Я полагаю, потому что у службы jwt.generate есть флаг пропуска перехватчика, это вызывает у меня проблему. К сожалению, я не знаю, как справиться с этим. Jwt.generate внутри перехватчика вызывает перехватчик.

0 ответов

Другие вопросы по тегам