I have 2 REST applications: main API and Auth API. I configured Nginx above them, so that the request goes to auth API first and if auth succeeded, continues in main API.
When Auth API returns 401 or 403, I would like to return error code to the client in response as JSON. However, as I googled, Nginx doesn't support passing response body to the client from auth_request
. So I thought I could set the error code in Auth API as a response header and generate JSON response from it in Nginx using error_page
directive. Here is my Nginx configuration:
server {
listen 80;
server_name 127.0.0.1;
if_modified_since off;
expires off;
etag off;
set $api_base_url "http://api:9090";
set $service_user_base_url "http://auth-api:9091";
resolver 127.0.0.11 ipv6=off;
location /some-api-endpoint {
auth_request /validate_token;
auth_request_set $authorization $upstream_http_authorization;
proxy_pass $api_base_url;
proxy_intercept_errors on;
add_header Authorization $authorization;
error_page 401 = @handle_auth_401;
error_page 403 = @handle_auth_403;
}
location = /validate_token {
internal;
if ($request_method = OPTIONS) {
return 200;
}
proxy_pass $service_user_base_url/validation;
proxy_pass_request_body off;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Method $request_method;
}
location @handle_auth_401 {
default_type application/json;
return 401 '{"failure":{"type":"$upstream_http_x_auth_failed_error_code"}}';
}
location @handle_auth_403 {
default_type application/json;
return 403 '{"failure":{"type":"$upstream_http_x_auth_failed_error_code"}}';
}
}
However, the response I receive is {"failure":{"type":""}}
. When I call auth API's /validation
endpoint, I receive the header 'X-Auth-Failed-Error-Code' in response, but for some reason Nginx can't resolve it. Seems like I miss something.
Have someone tried this or faced the same problem before? Would really appreciate any help.
UPD:
Okay, I have managed to solve this issue, using another auth_request_set
directive in API location:
location /some-api-endpoint {
auth_request /validate_token;
auth_request_set $authorization $upstream_http_authorization;
auth_request_set $x_auth_failed_error_code $sent_http_x_auth_failed_error_code;
...
Then I use new variable in named location like this:
location @handle_auth_401 {
default_type application/json;
return 401 '{"failure":{"type":"$x_auth_failed_error_code"}}';
}