Laravel 5 / Nginx - странное поведение заголовков CORS, установленных на уровне веб-сервера
Я сталкиваюсь с этой проблемой:
Я установил заголовки CORS в nginx, таким образом:
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
Другими словами, правильные учетные данные дают мне код состояния 200 с заголовками CORS, в то время как неправильные учетные данные дают мне код состояния 401 без заголовков CORS.
Вот метод аутентификации контроллера пользователя:
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 я не могу прочитать ответ в браузере (который использует XHR через React fetch
)
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 не указан или имеет пустое значение списка, то совпадение не требуется. Поэтому в следующей директиве для выходного заголовка сервера задается пользовательское значение для любого кода состояния и любого типа содержимого:
more_set_headers "Server: my_server";