当前位置: 首页 > 知识库问答 >
问题:

CORS飞行前请求-标头中的自定义auth令牌-Spring和Angular 4

孔驰
2023-03-14
@Override
public void doFilter(final ServletRequest req, final ServletResponse res,
                     final FilterChain chain) throws IOException, ServletException {
    final HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods",
            "POST, GET, PUT, OPTIONS, DELETE, PATCH");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with, x-auth-token, Content-Type");
    response.setHeader("Access-Control-Expose-Headers", "x-auth-token");
    response.setHeader("Access-Control-Allow-Credentials", "true");

    final HttpServletRequest request = (HttpServletRequest) req;

    if (request.getMethod().equals("OPTIONS")) {
        try {
            response.getWriter().print("OK");
            response.getWriter().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {
        chain.doFilter(request, response);
    }
}

所以这里的x-auth-token是一个类似JWT的标记。

在我的Angular代码中,我只需将令牌添加为x-auth-token,如下所示:

getAll() {
    return this.http.get('http://127.0.0.1:8080/module', this.jwt()).map((response: Response) => response.json());
}

private jwt() {
    // create authorization header with jwt token
    let token = localStorage.getItem('user');
    let obj = JSON.parse(token)
    console.log(obj.token.token)
    if (obj.token) {
        let headers = new Headers({
            'x-auth-token': obj.token.token,
            'Content-Type': "application/json"
        });
        return new RequestOptions({ headers: headers });
    }
}

请注意,我的身份验证/注册路由工作正常,我只是在将x-auth-token标头传输到Spring服务器时遇到了困难。

谢谢,

共有1个答案

艾焕
2023-03-14

首先,postman和curl不是测试CORS的好方法,因为它们不像标准浏览器那样执行相同的起源策略。即使在浏览器中失败的情况下,它们也会工作。

其次,浏览器预先启动请求的原因是,它不是一个简单的请求,因为x-auth-token标头和application/json内容类型。简单请求中只允许application/x-www-form-urlencodedmultipart/form-datatext/plain内容类型。

我假设问题出在选项响应上。确保它包括所有相关的标题。它可能失败了,或者您正在丢失添加的标头,因为您处理它的方式与其他响应不同。

 类似资料:
  • 在调试我遇到的CORS问题时,我发现了以下行为。Chrome发出以下选项预检请求(由Chrome本身在CURL中重写): 以下情况下服务器对此请求的响应: 是响应“无效CORS请求”的主体。如果我重复该请求,删除标头“Access Control request Method”(仅该标头),则OPTIONS请求将成功,并得到以下响应: 然而,有问题的头是CORS规范标准头,所以它不应该阻止请求成功

  • 我有一个Spring Boot/Spring Data REST服务,允许访问许多资源。其中一些资源(例如)可以自由访问,其他资源(例如)需要基本的HTTP身份验证。通过使用CURL测试REST服务,所有工作都按预期进行。当我试图从Angular2 web应用程序访问服务时,问题就会出现。

  • 后端返回 我有个请求 它在Chrome中工作,但对Firefox来说 跨源请求被阻止:同源策略不允许在<...cut...>读取远程资源。(原因:在CORS预飞行通道的CORS标头'Access-Control-Allow-Headers'中缺少令牌'X-Auth')。[了解详细信息]跨源请求被阻止:相同的源策略不允许在<...CUT...>读取远程资源。(原因:CORS请求未成功)

  • 我不清楚CORS头(Access-Control-Allow-Origin等)是否应该只出现在飞行前请求(OPTIONS方法)中,还是也出现在资源的头中(我试图使用XHR发布)

  • 我让这个项目在Angular 8中运行,并使用飞行前和实际的api调用api。而且我们在它的网络安全上有一个问题,因为飞行前的选项没有标题严格的传输安全性:max age=31536000;includeSubDomains,而实际的GET api有一个。 您是否知道如何以及在哪里添加严格运输安全:max-age=31536000;包括预飞行和实际请求下的子域,以便两个请求将具有相同的标头?

  • 我使用AJAX请求通过POST将数据发送到另一个域。因为我的内容类型不是标准的(它是JSON格式),所以需要一个飞行前请求。(使用请求方法:选项) 如维基百科跨域XHR调用图表中所述 我想知道这是否很费时,因为浏览器将必须到达服务器两次或不?也许这取决于每个浏览器的行为? 通过使用内容类型“纯文本”来避免飞行前请求,我是否获得了一些时间?