1.首先新建一个拦截器jwt.interceptor.ts:
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpClient,
} from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
public refreshToken$: Subject<boolean> = new Subject();
constructor(private http: HttpClient) {
this.refreshToken$.pipe(debounceTime(1000 * 300)).subscribe((v) => {
this.http.get(`/auth/refreshToken`).subscribe((res: any) => {
if (res.Success) {
localStorage.setItem('ACCESS_TOKEN', res.Data.refreshToken);
localStorage.setItem(
'ACCESS_TOKEN_EXPIRE',
JSON.stringify({
time: new Date().getTime(),
expires: res.Data.refreshExpiresIn,
})
);
console.log('更新token成功');
} else {
console.error('更新token失败');
}
});
});
}
//请求拦截
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const token = localStorage.getItem('ACCESS_TOKEN');
const authReq = req.clone({
headers: req.headers
.set('Authorization', `Bearer ${token}`)
.set('token', `${token}`),
});
// 检查token是否过期,如果过期自动续签。
const tokenTime = localStorage.getItem('ACCESS_TOKEN_EXPIRE');
if (tokenTime && token) {
const tempTokenTime = JSON.parse(tokenTime);
if (Number(tempTokenTime.time) && Number(tempTokenTime.expires)) {
if (
new Date().getTime() - Number(tempTokenTime.time) >
(Number(tempTokenTime.expires) * 1000) / 3
) {
this.refreshToken$.next(true);
}
}
}
return next.handle(authReq);
}
}
2.在app.module.ts里注入。
由于拦截器是 HttpClient 服务的可选依赖,所以你必须在提供 HttpClient 的同一个(或其各级父注入器)注入器中注册提供这些拦截器。由于在 AppModule 中导入了 HttpClientModule,因此本应用在其根注入器中提供了 HttpClient。所以同样要在 AppModule 中注册提供这些拦截器。
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { JwtInterceptor } from './common/interceptor/jwt.interceptor';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule
],
providers: [{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }], // InterceptorA 注册语句
bootstrap: [AppComponent]
})
export class AppModule {
constructor() {
}
}
网友评论