问题描述
最近,我在基于Springboot和Angualr2的App中引入了JWT身份验证.在那里"中,我尝试通过在Angualr代码中传递以下JWT令牌来发出POST请求
Recently i have introduced JWT authentication to my Springboot and Angualr2 based App.In There i tried to do a POST request by passing the JWT token as below in my Angualr code
save(jobId: number, taskId: number, note: Note) {
return this.http.post(environment.APIENDPOINT + '/jobs/' + jobId + '/tasks/' + taskId + '/notes', note, this.setHeaders()).map((response: Response) => response.json());
}
private setHeaders() {
// create authorization header with jwt token
let currentUser = JSON.parse(localStorage.getItem('currentUser'));
console.log("Current token---"+ currentUser.token);
if (currentUser && currentUser.token) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('authorization','Bearer '+ currentUser.token);
let r = new RequestOptions({ headers: headers })
return r;
}
}
但是,在服务器端,它返回状态代码401.问题出在Springboot端,它如下所示检查授权标头,并返回null
However in the server side it returns status code 401. The issue is in the Springboot side it checks the authorization header as below and it returns null
String authToken = request.getHeader("authorization ");
然后,我查看了请求标头,它在Access-Control-Request-Headers下具有授权标头,如下所示.但是它对服务器端不可见.
Then i had a look at the request header and it has the authorization header under Access-Control-Request-Headers as below. But it is not visible to the server side.
然后,我进一步阅读,发现这可能与CORS配置有关.所以我修改了我的CORS配置过滤器,使其具有如下的addExposedHeader
Then i read further and found that this could be an issue with CORS configuration. So i have modified my CORS configuration filter to have addExposedHeader as below
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addExposedHeader("authorization");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
//config.addExposedHeader("Content-Type");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
服务器仍然抱怨找不到授权头.我在这里想念任何东西吗?感谢您的帮助
Still the server complains that it can not find the Authorization header. Did i miss any thing here? Appreciate your help
解决方案
阅读下面的sideshowbarker评论后,我能够理解问题的基本知识.在我的项目"中,我有一个JWT令牌过滤器,并且在其中始终检查Authorization标头.然后我如下修改了它,现在它可以按预期工作了
After reading the sideshowbarker's comment below, i was able to understand the basics behind the issue.In My Project I have a JWT token filter and inside that it always checks the Authorization header. Then i have modified it as below and now it works as expected
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
try {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
}else{
String authToken = request.getHeader(this.tokenHeader);
jWTTokenAuthenticationService.parseClaimsFromToken(authToken);
--
}
chain.doFilter(request, response);
}Catch(AuthenticationException authEx){
SecurityContextHolder.clearContext();
if (entryPoint != null) {
entryPoint.commence(request, response, authEx);
}
}
}
推荐答案
您需要将服务器配置为不要求对OPTIONS
请求进行授权(即,将请求发送到的服务器,而不是为您的服务器提供服务的服务器)前端代码).
You need to configure the server to not require authorization for OPTIONS
requests (that is, the server the request is being sent to — not the one serving your frontend code).
那是因为发生了什么事
- 您的代码告诉您的浏览器它想要发送带有
Authorization
标头的请求. - 您的浏览器说,好吧,带有
Authorization
头的请求要求我执行CORS预检OPTIONS
,以确保服务器允许带有Authorization
头的请求. - 您的浏览器将
OPTIONS
请求发送到服务器而没有Authorization
标头,因为OPTIONS
检查的整个目的是查看是否可以包含该标头./li> - 您的服务器看到了
OPTIONS
请求,但没有以表明它允许请求中使用Authorization
标头的方式对其进行响应,而是由于缺少标头而以401拒绝了它. - 您的浏览器期望CORS预检得到200或204的响应,但会得到401的响应.因此,您的浏览器会在那里停止,并且永远不会尝试通过您的代码发出
POST
请求.
- Your code’s telling your browser it wants to send a request with the
Authorization
header. - Your browser says, OK, requests with the
Authorization
header require me to do a CORS preflightOPTIONS
to make sure the server allows requests with theAuthorization
header. - Your browser sends the
OPTIONS
request to the server without theAuthorization
header, because the whole purpose of theOPTIONS
check is to see if it’s OK to include that header. - Your server sees the
OPTIONS
request but instead of responding to it in a way that indicates it allows theAuthorization
header in requests, it rejects it with a 401 since it lacks the header. - Your browser expects a 200 or 204 response for the CORS preflight but instead gets that 401 response. So your browser stops right there and never tries the
POST
request from your code.
更多详细信息:
Further details:
问题屏幕快照中的Access-Control-Request-Headers
和Access-Control-Request-Method
请求标头表明浏览器正在执行 CORS飞行前选项请求.
The Access-Control-Request-Headers
and Access-Control-Request-Method
request headers in the screenshot in the question indicate the browser’s doing a CORS preflight OPTIONS request.
并且请求中出现Authorization
和Content-Type: application/json
请求标头是触发浏览器执行CORS预检的原因-通过在尝试代码中的POST
请求之前向服务器发送OPTIONS
请求.而且由于OPTIONS
预检失败,因此浏览器就在那里停止并且从不尝试POST
.
And the presence of the Authorization
and Content-Type: application/json
request headers in your request are what trigger your browser do that CORS preflight — by sending an OPTIONS
request to the server before trying the POST
request in your code. And because that OPTIONS
preflight fails, the browser stops right there and never attempts the POST
.
因此,您必须确定请求发送到服务器上服务器中当前服务器端代码的哪一部分,以使其要求对OPTIONS
请求进行授权,并对其进行更改,以使其对OPTIONS
作出响应.无需授权即可获得200或204成功响应.
So you must figure out what part of the current server-side code on the server the request is being sent to causes it to require authorization for OPTIONS
requests, and change that so it instead responds to OPTIONS
with a 200 or 204 success response without authorization being required.
有关特别启用OPTIONS
-启用Spring服务器的特定帮助,请参见以下答案:
For specific help on OPTIONS
-enabling a Spring server in particular, see the following answers:
- 为选项Http方法禁用Spring Security
- 对预检的响应无效HTTP状态码401-Spring
- AngularJS&具有ROLE_ANONYMOUS的Spring Security仍返回401
- Disable Spring Security for OPTIONS Http Method
- Spring CorsFilter does not seem to work still receiving a 401 on preflight requests
- Response for preflight has invalid HTTP status code 401 - Spring
- AngularJS & Spring Security with ROLE_ANONYMOUS still returns 401
这篇关于HTTP状态代码401,即使我在请求中发送凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!