为了账号安全,请及时绑定邮箱和手机立即绑定

HTTP状态代码401,即使我在请求中发送凭据

/ 猿问

HTTP状态代码401,即使我在请求中发送凭据

aluckdog 2019-11-04 10:10:41

最近我已经介绍了智威汤逊验证我的Springboot和基于Angualr2应用。在There中,我尝试通过在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());


}

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


String authToken = request.getHeader("authorization ");

然后,我看了一眼请求头,它具有在访问控制请求报头的授权头下面。但是它对服务器端不可见。

然后,我进一步阅读,发现这可能与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);

}

服务器仍然抱怨找不到授权头。我在这里想念任何东西吗?感谢您的帮助


查看完整描述

2 回答

?
素胚勾勒不出你

在“我的项目”中,我有一个JWT令牌过滤器,并且在其中始终检查Authorization标头。然后我已经如下修改它,现在它可以按预期工作


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

    }

}

}


查看完整回答
反对 回复 2019-11-04
?
白衣染霜花

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


那是因为发生了什么事:


您的代码告诉您的浏览器它想发送带有Authorization标头的请求。

您的浏览器说,好吧,带Authorization标头的请求要求我进行CORS预检OPTIONS,以确保服务器允许带Authorization标头的请求。

您的浏览器将不带标头的OPTIONS请求发送到服务器,因为检查的整个目的是查看是否可以包含该标头。AuthorizationOPTIONS

您的服务器看到了OPTIONS请求,但没有以表明允许Authorization请求头的方式响应,而是使用401来拒绝请求,因为它缺少头。

您的浏览器期望CORS预检响应为200或204,但会得到401响应。因此,浏览器就在那里停止,并且永远不会尝试POST从您的代码发出请求。

更多详情:


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


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


因此,您必须确定请求发送到服务器上服务器当前服务器端代码的哪一部分,以使其要求对OPTIONS请求进行授权,然后进行更改以使其响应OPTIONS 200或204成功响应而无需授权。


查看完整回答
反对 回复 2019-11-04

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信