Laravel 5 / Nginx - 在 Web 服务器级别设置的 CORS 标头的奇怪行为

Posted

技术标签:

【中文标题】Laravel 5 / Nginx - 在 Web 服务器级别设置的 CORS 标头的奇怪行为【英文标题】:Laravel 5 / Nginx - strange behavior of CORS headers set at web server level 【发布时间】:2016-07-04 05:21:48 【问题描述】:

我正面临这个问题:

我在 nginx 中设置了 CORS 头,这样:

add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET,POST,PUT,OPTIONS";
add_header Access-Control-Allow-Headers "Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Content-Type";

我需要调用我的 API 端点来验证用户并发布 JWT。发生的情况是,如果身份验证正常,服务器会使用以下标头进行响应:

Access-Control-Allow-Headers →Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Content-Type
Access-Control-Allow-Methods →GET,POST,PUT,OPTIONS
Access-Control-Allow-Origin →*
Cache-Control →no-cache
Connection →keep-alive
Content-Encoding →gzip
Content-Type →application/json
Date →Thu, 17 Mar 2016 17:13:34 GMT
Server →nginx
Strict-Transport-Security →max-age=10886400; includeSubdomains
Transfer-Encoding →chunked
Vary →Accept-Encoding
X-Content-Type-Options →nosniff
X-Frame-Options →SAMEORIGIN
X-XSS-Protection →1; mode=block

但是,如果凭据无效,我会得到这些

Cache-Control →no-cache
Connection →keep-alive
Content-Encoding →gzip
Content-Type →application/json
Date →Thu, 17 Mar 2016 17:14:58 GMT
Server →nginx
Transfer-Encoding →chunked
Vary →Accept-Encoding

换句话说,正确的凭据给我一个带有 CORS 标头的 200 状态代码,而错误的凭据给我 401 状态代码 没有 CORS 标头

这里是用户控制器的auth方法:

public function authenticate(Requests\AuthenticateUserRequest $request)
    
        $credentials = $request->only('username', 'password');
        $customClaims = ['tfa' => null];

        try
        
            // attempt to verify the credentials and create a token for the user
            if (!$token = JWTAuth::attempt($credentials, $customClaims))
            
                // when this is the response, CORS headers are not set by nginx 
                return response()->json(Utils::standardResponse(false, 'Invalid credentials'), 401);
            
         catch (JWTException $e)
        
            // something went wrong whilst attempting to encode the token
            return response()->json(Utils::standardResponse(false, 'Could not create token'), 500);
        

       [...email notification and other stuff...]

        // all good so return the token
        return response()->json(Utils::standardResponse(true, '', compact('token')));
    

注意我正在使用 Postman 进行测试,但实际问题是没有 CORS 标头我无法读取浏览器中的响应(通过 React fetch 使用 XHR)

【问题讨论】:

【参考方案1】:

想通了。 Nginx add_header 确实仅在成功响应时设置标题(200 状态代码)。

我确实需要使用headers_more nginx 的模块。特别是,我做到了:

more_set_headers "Access-Control-Allow-Origin: *";
more_set_headers "Access-Control-Allow-Methods: GET,POST,PUT";
more_set_headers "Access-Control-Allow-Headers: Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Content-Type";

按照文档中的建议,

如果 -s 或 -t 未指定或列表值为空,则 不需要匹配。因此,以下指令设置 服务器输出标头到 any 状态代码和 any 的自定义值 内容类型:

more_set_headers "Server: my_server";

【讨论】:

当 nginx 版本 =1.7.5 时,您始终可以从这里引用 @ 987654322@

以上是关于Laravel 5 / Nginx - 在 Web 服务器级别设置的 CORS 标头的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

ini 使用nginx缓存并响应Web请求#nginx #php #performance #laravel

使用 nginx 在 laravel forge 上集成 Laravel 5.2 wordpress

Laravel 5/ 5.4 分页器在 NGINX 生产环境中不工作

markdown NGINX PHP 7.2 LARAVEL 5.6

Laravel 5.3 在 ubuntu16.04 nginx 中使用命令 composer install --no-dev 上传

Laravel + NGINX 给 403 禁止