在angular4 项目中,每次请求服务端需要添加头部信息AccessToken作为认证的凭据。但如果在每次调用服务端就要写代码添加一个头部信息,会变得很麻烦。可以使用angular4的HttpClient来拦截每个请求,然后在头部添加上信息。
直接上代码实践
一、创建拦截器Service,实现HttpInterceptor的 intercept 方法
import { Injectable, Injector} from ' @angular/core ' ;
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from ' @angular/common/http ' ;
import {Observable} from ' rxjs/Observable ' ;
import ' rxjs/add/operator/do ' ;
import {AuthenticationService} from ' ./auth/authentication.service ' ; // 用于获得AccessToken的服务类
import {environment} from ' environments/environment ' ;
/* *
* HTTP拦截器,设置头部信息
*/
@Injectable()
export class BaseHttpInterceptorService implements HttpInterceptor {
authService: AuthenticationService;
skipAuth: [ string ];
constructor( private inject: Injector) {
// 用户登录或认证请求则不需要添加头部AccessToken信息
this .skipAuth = [
`${environment.serverUrl} /api/v1/User/ login`,
];
}
/* *
* 拦截器拦截请求
* @param {HttpRequest<any>} req
* @param {HttpHandler} next
* @returns {Observable<HttpEvent<any>>}
*/
intercept(req: HttpRequest <any>, next: HttpHandler): Observable<HttpEvent<any>> {
this .authService = this .inject. get (AuthenticationService); // 注意此句
const req_started = Date.now();
let authReq;
/* *
* 如果是跳过认证的链接,则不添加头部信息
*/
if ( this .isSkipAuth(req.url)) {
authReq = req.clone();
} else {
const access_token = `Bearer ${ this .authService.getAccessToken( ' 563151811@qq测试数据 ' )}`;
authReq = req.clone({
setHeaders: {
Authorization: access_token
}
});
}
return next.handle(authReq). do ( event => {
if ( event instanceof HttpResponse) {
const elapsed = Date.now() - req_started;
console.log(`Request for ${req.urlWithParams} took ${elapsed} ms`);
}
});
}
/*
*是否跳过添加头部认证
*/
isSkipAuth(url: string ) {
let isMatch = false ;
this .skipAuth.forEach((reg_url: string ) => {
if ( ! isMatch) {
if (url.search(reg_url) >= 0 ) {
isMatch = true ;
}
}
});
return isMatch;
}
}
二、注册拦截器,在APPModule中,添加如下代码
{
provide: HTTP_INTERCEPTORS,
useClass: BaseHttpInterceptorService, // 上边定义的拦截器名字
multi: true
},
三、每个请求服务端数据的Service依赖HttpClient,而不是http。
那么一个基础的拦截器已经完成了,但是,你会发现调用认证服务Service的时候,会报错: Cyclic dependency error with HttpInterceptor , 如果添加了第一步代码中注意点那段代码后,又会发现OK了。
这是 依赖注入循环嵌套:A依赖B,B中又引用A。
官方文档中采用 forwardRef, 但是发现没用。在Stack Overflow中看到有人采用上述方法成功解决问题。 https://github测试数据/angular/angular/issues/18224
如需要更详细的代码或有问题,请联系我
?
查看更多关于Angular4---认证---使用HttpClient拦截器,解决循环依赖引用的问题的详细内容...