Angularjs Post没有将标头发送到Spring JWT

Posted

技术标签:

【中文标题】Angularjs Post没有将标头发送到Spring JWT【英文标题】:Angularjs Post not sending headers to Spring JWT 【发布时间】:2016-07-14 09:10:34 【问题描述】:

我有一个由 AngularJs 构建的 Web 应用程序和一个由 Spring 构建的后端应用程序,我正在使用 JWT 来保护我的应用程序。 使用 Get 方法一切正常,在后端级别我得到了我期望的不记名令牌,因此我可以返回私人信息。但是使用 POST 方法,不发送不记名令牌。 我不知道这是后端还是前端层的问题。 这里有我的代码:

AngularJS

$http(
        method: 'POST',
        url: SessionService.apiUrl + '/category/create',
        headers: 
          'Accept': 'application/json','Content-Type': 'application/json; 
           charset=UTF-8;', 'Authorization': 'Bearer ' + SessionService.getToken()
       ,
        data: params
 )

对于 GET 方法,我有完全相同的(没有参数和方法 GET)并且它正在工作。

在后端:

@RequestMapping(value = "/category/create", method = RequestMethod.POST)
    public @ResponseBody
    Response add(@RequestBody CategoryBO request) 
...

为了获得授权标头,我通过以下方式使用 io.jsonwebtoken 库:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException 
        String authorizationHeader = request.getHeader("authorization");

使用 Postman 后端运行良好,但使用 angularjs 则不行。

GET - 请求标头:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6,pt;q=0.4
Authorization:Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJmYWJpYW4uYW5nZWxvbmkiLCJyb2xlcyI6IkFETUlOIiwiaWF0IjoxNDU5MDE5MTg0fQ.QAPZDbyavambfdK9LJUQWyzSRAuELvg_IGTjFdsm6cc
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/49.0.2623.87 Safari/537.36

POST - 请求标头

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6,pt;q=0.4
Access-Control-Request-Headers:accept, authorization, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36

【问题讨论】:

检查浏览器开发工具网络中的实际请求以及检查控制台是否有错误。我怀疑你有 CORS 问题,需要确保它在服务器 api 端点上实现 在我的 spring 控制器中,我有“@CrossOrigin(origins = "localhost:3000")",当我调试时,我可以看到调用了 JWT 方法,并且我可以看到 Authorization 标头即将到来在 POST 方法中为 NULL,在 GET 中具有正确的值。我需要做些什么特别的事情吗? 并没有说明上述请求中实际发送的内容。或者,如果您正在处理 OPTIONS 预检请求并在其上设置了标头,或者如果您遇到 CORS 错误您的浏览器是首选的调试工具 @charlietfl 我在评论中添加了 Request 标头,您可以在其中看到它们如何根据它是 GET 还是 POST 进行更改。我想两者应该相同,也许这就是问题......而且我认为如果我可以在服务器上调试是因为它不是 CORS 问题,而且对于 GET 和 POST 请求也应该是相同的,对吧? 可能会尝试设置withCredentials ..see docs。不确定请求标头如何设置任何Access-Control...这些通常是响应标头 【参考方案1】:

感谢@user2858970 的解释。我发现它非常清晰。

要解决问题,您基本上需要处理两件事:

    在您的服务器中启用 CORS,因为您的服务器必须知道它正在从不同域中的客户端获取请求。 在 Spring 安全级别启用 CORS 以允许它利用在 Spring MVC 级别定义的配置。

我已经把解释和代码放在一起回答CORS with spring-boot and angularjs not working 。

【讨论】:

【参考方案2】:

我遇到了类似的问题,然后我意识到前端在实际执行 HTTP.OPTIONS 请求之前触发了预检请求。 More info here

此类请求将没有授权令牌,因此对控制器的访问将失败。最自然的解决方案是通过让所有 OPTIONS 请求传递来设置应用程序的安全性。

这是可以做到的

设置配置,如you can see here 将您的应用程序肯定拥有的 CorsFilter 设置为 you can see here

希望对你有帮助

【讨论】:

以上是关于Angularjs Post没有将标头发送到Spring JWT的主要内容,如果未能解决你的问题,请参考以下文章

防止 nuxt auth 将授权标头发送到外部 url

Node.js,Express:将标头发送到客户端后无法设置标头

ERR_HTTP_HEADERS_SENT:在 ServerResponse 将标头发送到客户端后无法设置标头

如何解决“将标头发送到客户端后无法设置标头”

为啥我在 Nodejs 中收到“无法在将标头发送到客户端后设置标头”错误?

GraphQL 突变“在将标头发送到客户端后无法设置标头”