typescript Angular 6 - 身份验证令牌拦截器不添加标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51447545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular 6 - Auth token interceptor not adding headers
提问by kriskanya
Using Angular 6, I have tried many different approaches over the last two days, with the latest riffing off of this post: https://stackoverflow.com/a/47401544. However, the header is still not being set on requests.
使用 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
}
}
});
}
}
If I log out request
, the request.headers.lazyUpdate
array is being updated with 3 items, but I don't see the Authorization
header in the request it's intercepting.
如果我注销request
,该request.headers.lazyUpdate
数组将更新为 3 个项目,但我Authorization
在它拦截的请求中看不到标头。
request.headers.lazyUpdate
:
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
is empty---could this be the problem?)
(request.headers.headers
是空的---这可能是问题吗?)
app.module.ts:
app.module.ts:
providers: [
{provide: HTTP_INTERCEPTORS, useClass: AuthTokenInterceptor, multi: true},
],
What leads me to think it's an interceptor issue is that if I manually add the headers to the request, I don't get a 401
and the request returns the proper data and a 200
:
让我认为这是一个拦截器问题的原因是,如果我手动将标头添加到请求中,我不会得到 a401
并且请求返回正确的数据和 a 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)
);
Is there anything I may be overlooking? Thanks.
有什么我可能会忽略的吗?谢谢。
EDIT:
编辑:
As I mention in a comment below, I was returning next.handle
twice. This is the solution I ended up going with:
正如我在下面的评论中提到的,我回来了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);
}
}
采纳答案by lupa
You could try a simpler version of it.(just like your reference link does
)
你可以试试更简单的版本。( 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);
}
You don't have to handle the error
here
since the point of intercepter
here(in your context) is to clone(that means whenever we took request, we clone it, then do whatever we want and send it away).
We could add more headers more data
And it will be sent away, then eventually coming back with return from Api
And leave the handle problem to the service
that call the httpRequest
(eg: then, catch, pipe
,...).
您不必处理error
此处,
因为intercepter
此处(在您的上下文中)的重点是克隆(这意味着无论何时我们接受请求,我们都会克隆它,然后做任何我们想做的事情并将其发送出去)。
我们可以添加更多的标题更多的数据
它会被发送出去,然后最终从 Api 返回
并将处理问题留给service
调用httpRequest
(例如:then, catch, pipe
,...)。
Again, you declared this in app.module.ts
which mean all
of the request
to api in your app will be intercept, and what if I want to handle a specific request with the error message Nothing here
?, and if you do some complicated logic, it could affect all request.
And about your code above, I haven't try it, but I think their could be something wrong happened when you nested like that or so, you should put the break point their and tried to debug what happened.
同样,你宣称这app.module.ts
其中的意思all
的request
在您的应用程序的API将是拦截,并且如果我要处理与错误消息的具体要求Nothing here
?,如果你做一些复杂的逻辑,它可能会影响所有请求。
关于您上面的代码,我还没有尝试过,但是我认为当您像这样嵌套时可能会发生错误,您应该放置断点并尝试调试发生的事情。
回答by enno.void
So the first issue i see here is that u dont return if there is no value in localStorage. i would structure the interceptor like this:
所以我在这里看到的第一个问题是,如果 localStorage 中没有值,你就不会返回。我会像这样构造拦截器:
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);
}
}
回答by kriskanya
Full solution I went with:
我使用的完整解决方案:
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);
}
}