我正在使用jwt进行身份验证。我在刷新时遇到了麻烦。我认为这可能是由于我缺乏 rxjs 可观察对象和运算符的经验所致。我使用 auth.service.ts
的这些方法从后端获取刷新令牌 getNewAccessToken(refreshToken: string){
return this.httpClient.post<Token>(`${this.baseService.baseUrl}auth-token-refresh/`, { refresh: refreshToken }, this.baseService.httpOptions).pipe(
map((response:Token) => {
this.cookieService.set(environment.tokenAccessName, response.access, null, '/', null, null, 'Strict');
return response;
}
));
}
getAuthToken() {
return this.cookieService.get(this.tokenAccessName);
}
getRefreshToken() {
return this.cookieService.get(this.tokenRefreshName);
}
hasValidToken() {
if (this.getAuthToken())
return !helper.isTokenExpired(this.getAuthToken());
else
return false;
}
这是我的拦截器 auth-interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse
} from '@angular/common/http';
import { AuthService } from '../services/auth.service';
import { throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { Token } from '../models/token';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler) {
const authToken = this.authService.getAuthToken();
if (authToken) {
if (this.authService.hasValidToken()) {
request = this.addAuthenticationToken(request);
}
}
return next.handle(request).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.handle401Error(request, next);
} else {
return throwError(error);
}
}));
}
handle401Error(request: HttpRequest<any>, next: HttpHandler) {
const refreshToken = this.authService.getRefreshToken();
this.authService.getNewAccessToken(refreshToken).subscribe(
(response: Token) => {
this.addAuthenticationToken(request);
return next.handle(request);
},
error => throwError(error)
)
}
addAuthenticationToken(request: HttpRequest<any>) {
const authToken = this.authService.getAuthToken();
return request.clone({
headers: request.headers.set('Authorization', 'Bearer ' + authToken),
});
}
}
我的 ide 显示以下错误
Property 'intercept' in type 'AuthInterceptor' is not assignable to the same property in base type 'HttpInterceptor'.
Type '(request: HttpRequest<any>, next: HttpHandler) => Observable<unknown>' is not assignable to type '(req: HttpRequest<any>, next: HttpHandler) => Observable<HttpEvent<any>>'.
Type 'Observable<unknown>' is not assignable to type 'Observable<HttpEvent<any>>'.
Type 'unknown' is not assignable to type 'HttpEvent<any>'.
Property 'type' is missing in type '{}' but required in type 'HttpUserEvent<any>'.
还有
Argument of type '(error: any) => void | Observable<never>' is not assignable to parameter of type '(err: any, caught: Observable<HttpEvent<any>>) => ObservableInput<any>'.
Type 'void | Observable<never>' is not assignable to type 'ObservableInput<any>'.
Type 'void' is not assignable to type 'ObservableInput<any>'.
我认为我可能对返回类型有误,但我无法弄清楚出了什么问题
答案 0 :(得分:0)
我终于找到了解决方案。也许有人可以尝试改善它 我进行了以下更改,现在可以使用了 在 intercept 签名中添加 Observable> ,导致我的问题中解释的第一个问题消失了。对于第二个问题,我遵循问题评论中的建议。 拦截器类
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.authService.hasValidToken()) {
request = this.addAuthenticationToken(request);
}
return next.handle(request).pipe(
catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.handle401Error(request, next);
} else {
throw error;
}
}));
}
handle401Error(request: HttpRequest<any>, next: HttpHandler) {
return this.authService.getNewAccessToken().pipe(
switchMap((response: Token) => {
return next.handle(this.addAuthenticationToken(request));
})
)
}
addAuthenticationToken(request: HttpRequest<any>) {
const authToken = this.authService.getAuthToken();
return request.clone({
setHeaders: {
'Authorization': `Bearer ${authToken}`
}
});
}
}
身份验证服务中获得刷新令牌的功能已被修改为
getNewAccessToken(){
return this.httpClient.post<Token>(`${this.baseService.baseUrl}auth-token-refresh/`, { refresh: this.getRefreshToken() }, this.baseService.httpOptions).pipe(
tap((response:Token) => {
this.cookieService.set(environment.tokenAccessName, response.access, null, '/', null, null, 'Strict');
}
));
}