HTTP状态代码401,即使我正在发送授权请求标头

ket*_*eth 5 javascript httprequest cors spring-boot angular

最近我在我的Springboot和基于Angualr2的应用程序中引入了JWT身份验证.在那里我尝试通过在我的Angualr代码中传递如下的JWT令牌来执行POST请求

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());

}
Run Code Online (Sandbox Code Playgroud)

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;

        }
    }
Run Code Online (Sandbox Code Playgroud)

但是在服务器端它返回状态代码401.问题是在Springboot端它检查授权头如下,它返回null

String authToken = request.getHeader("authorization ");
Run Code Online (Sandbox Code Playgroud)

然后,我查看了请求标头,并在Access-Control-Request-Headers下具有授权标头,如下所示.但它对服务器端是不可见的.

在此输入图像描述

然后我进一步阅读并发现这可能是CORS配置的问题.所以我修改了我的CORS配置过滤器以使addExposedHeader如下所示

@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);
}
Run Code Online (Sandbox Code Playgroud)

服务器仍然抱怨它无法找到Authorization标头.我在这里错过了什么吗?感谢您的帮助

在阅读下面的sideshowbarker评论后,我能够理解这个问题背后的基础知识.在我的项目中,我有一个JWT令牌过滤器,并且内部始终检查授权标头.然后我将其修改如下,现在它按预期工作

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

sid*_*ker 13

您需要将服务器配置为不需要授权OPTIONS请求(即,请求发送到的服务器 - 而不是服务于您的前端代码的服务器).

那是因为发生的事情是这样的:

  1. 您的代码告诉您的浏览器它想要使用Authorization标头发送请求.
  2. 您的浏览器说,好的,带有Authorization标头的请求要求我进行CORS预检OPTIONS,以确保服务器允许带有Authorization标头的请求.
  3. 您的浏览器将OPTIONS请求发送到没有Authorization标头的服务器,因为OPTIONS检查的全部目的是查看是否可以包含该标头.
  4. 您的服务器看到OPTIONS请求但不是以指示它允许Authorization请求中的标头的方式响应它,而是由于它缺少标头而拒绝它与401.
  5. 您的浏览器需要对CORS预检做出200或204的响应,而是获得401响应.因此,您的浏览器就在那里停止,从不尝试POST从您的代码中获取请求.

更多详情:

Access-Control-Request-HeadersAccess-Control-Request-Method在问题的截图请求头指示浏览器做了CORS预检OPTIONS请求.

您的请求中存在AuthorizationContent-Type: application/json请求标头是触发您的浏览器执行CORS预检的原因 - 通过在您的代码中OPTIONS尝试POST请求之前向服务器发送请求.而且由于该OPTIONS预检失败,浏览器就停在那里,从不尝试过POST.

因此,您必须弄清楚发送请求的服务器上当前服务器端代码的哪一部分使其需要对OPTIONS请求进行授权,并对其进行更改,以便在OPTIONS 没有授权的情况下响应200或204成功响应.

有关为特定于Spring服务器执行此操作的特定帮助,请参阅以下答案:


归档时间:

查看次数:

6521 次

最近记录:

5 年,11 月 前