提问人:kriskanya 提问时间:7/21/2018 最后编辑:kriskanya 更新时间:6/18/2020 访问量:20430
Angular 6 - 身份验证令牌拦截器不添加标头
Angular 6 - Auth token interceptor not adding headers
问:
使用 Angular 6,在过去的两天里,我尝试了许多不同的方法,这篇文章的最新内容是:https://stackoverflow.com/a/47401544。但是,仍未在请求上设置标头。
import {Inject, Injectable} from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse,
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do((event: HttpEvent<any>) => {
if (localStorage.getItem('id_token') != null) {
// Clone the request to add the new header.
const request = req.clone({
setHeaders: {
'Content-Type' : 'application/json; charset=utf-8',
'Accept' : 'application/json',
'Authorization': `Bearer ${localStorage.getItem('id_token')}`
}
});
return next.handle(request);
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
console.log('redirect auth interceptor')
// do a redirect
}
}
});
}
}
如果我注销,数组正在用 3 个项目更新,但我在它拦截的请求中没有看到标头。request
request.headers.lazyUpdate
Authorization
request.headers.lazyUpdate
:
{name: "Content-Type", value: "application/json; charset=utf-8", op: "s"}
{name: "Accept", value: "application/json", op: "s"}
{name: "Authorization", value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2Mzh9.tLTmPK46NhXSuqoCfZKgZcrQWzlNqLMI71-G0iy3bi8", op: "s"}
(request.headers.headers
是空的---这可能是问题所在吗?
app.module.ts:
providers: [
{provide: HTTP_INTERCEPTORS, useClass: AuthTokenInterceptor, multi: true},
],
导致我认为这是拦截器问题的原因是,如果我手动将标头添加到请求中,我不会得到一个并且请求返回正确的数据和一个:401
200
return this.http.get(environment.API_URL + 'list/supervise/' + encodeURIComponent(id),
{headers: new HttpHeaders().set('Authorization', `Bearer ${localStorage.getItem('id_token')}`)}).pipe(
map((res: any) => res.data)
);
有什么我可能忽略的吗?谢谢。
编辑:
正如我在下面的评论中提到的,我回来了两次。这是我最终采用的解决方案:next.handle
import {Injectable} from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('id_token');
req = req.clone({
setHeaders: {
'Authorization': `Bearer ${token}`
},
});
return next.handle(req);
}
}
答:
所以我在这里看到的第一个问题是,如果 localStorage 中没有值,则 u 不会返回。我会像这样构建拦截器:
export class AuthInterceptor implements HttpInterceptor {
private APIToken = null;
private defaultApplicationHeaders = {
'Content-Type': 'application/json'
}
buildRequestHeaders():HttpHeaders {
let headers = this.defaultApplicationHeaders;
// set API-Token if available
if(this.APIToken !== null) {
let authHeaderTpl = `Bearer ${this.APIToken}`;
headers['Authorization'] = authHeaderTpl
}
return new HttpHeaders(headers);
}
constructor() {
this.APIToken = localStorage.getItem('id_token')
}
intercept(req: HttpRequest<any>, next: HttpHandler) {
const headers = this.buildRequestHeaders();
const authReq = req.clone({ headers });
return next.handle(authReq);
}
}
您可以尝试更简单的版本。(just like your reference link does
)
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const jwt = localStorage.getItem('id_token');
if (!!jwt) {
req = req.clone({
setHeaders: {
Authorization: `Bearer ${jwt}`
}
});
}
return next.handle(req);
}
您不必处理 here,因为 here
(在您的上下文中)的重点是克隆(这意味着每当我们接受请求时,我们都会克隆它,然后做任何我们想做的事并将其发送出去)。
我们可以添加更多的标头,更多的数据
,它将被发送出去,然后最终从Api返回,
并将句柄问题留给调用(例如:,...)。error
intercepter
service
httpRequest
then, catch, pipe
同样,您声明了您的应用程序中 to api 的意思将被拦截,如果我想处理带有错误消息的特定请求怎么办?,如果您执行一些复杂的逻辑,它可能会影响所有请求。
关于你上面的代码,我还没有尝试过,但我认为当你这样嵌套时,它们可能会出错,你应该把断点放在他们身上,并尝试调试发生了什么。app.module.ts
all
request
Nothing here
评论
return next.handle(req).do((event: HttpEvent<any>) => {
return next.handle(request);
我选择的完整解决方案:
import {Injectable} from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('id_token');
req = req.clone({
setHeaders: {
'Authorization': `Bearer ${token}`
},
});
return next.handle(req);
}
}
评论
对于那些关注 msal-angular MsalHttpInterceptor 的人。
现在,我制作了自己的 MsalInterceptor 实现。
这是我的自定义代码块:
// #region own workaround in order not to put every api endpoint url to settings
if (!scopes && req.url.startsWith(this.settingsService.apiUrl)) {
scopes = [this.auth.getCurrentConfiguration().auth.clientId];
}
// #endregion
// If there are no scopes set for this request, do nothing.
if (!scopes) {
return next.handle(req);
}
PS:在protectedResourceMap https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1776 中为通配符投票
评论