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

Laravel 5 / Nginx - strange behavior of CORS headers set at web server level

我正面临这个问题:

我在nginx中设置了CORSheaders,是这样的:

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。发生的事情是,如果身份验证正常,服务器会响应以下 headers:

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

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

这是用户控制器的授权方法:

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

N.B。我正在使用 Postman 进行测试,但实际问题是没有 CORS headers 我无法读取浏览器中的响应(通过 React 使用 XHR fetch

想通了。 Nginx add_header 仅在成功响应时设置 headers (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";

按照文档中的建议,

If either -s or -t is not specified or has an empty list value, then no match is required. Therefore, the following directive set the Server output header to the custom value for any status code and any content type:

more_set_headers "Server: my_server";