nginx - njs - ngx_http_auth_request_module как вернуть 302 пользователю?
Я использую njs ngx_http_auth_request_module.
У меня есть такая функция js;
function introspectAccessToken(r) {
r.subrequest("/_oauth2_send_request",
function(reply) {
if (reply.status == 200) {
var response = JSON.parse(reply.responseBody);
if (response == true) {
r.return(204); // Token is valid, return success code
} else {
r.return(403); // Token is invalid, return forbidden code
}
} else {
// need 302 here
}
}
);
}
В документации говорится: «Если подзапрос возвращает код ответа 2xx, доступ разрешен. Если он возвращает 401 или 403, доступ запрещается с соответствующим кодом ошибки. Любой другой код ответа, возвращенный подзапросом, считается ошибкой». http://nginx.org/en/docs/http/ngx_http_auth_request_module.html
Мне нужно вернуть 302 пользователю, если подзапрос входит в блок «else».
Есть ли способ добиться этого? Если я установлю r.return (302), он покажет страницу ошибки в браузере, как сказано в документации.
1 ответ
Понятно - я не думаю, что тебе даже нужно
njs
сделать это. В случае, если ваша конечная точка интроспекции токена НЕ создана с помощью NJS и не проверяет, является ли токен допустимым json, но реализован на каком-то другом языке, эта конфигурация NGINX будет работать.
#cache for auth_request responses
proxy_cache_path /var/cache/nginx/oauth keys_zone=token_responses:1m max_size=2m;
#Your Server
server {
listen 80;
location / {
#Redirect Unauthed Request to some other location...
error_page 401 =302 http://localhost:9000/login;
auth_request /_auth_request;
proxy_pass http://127.0.0.1:8080;
}
location /_auth_request {
internal;
proxy_pass http://127.0.0.1:8090;
###place caching responses here to be more effective;
proxy_cache token_responses; # Enable caching
proxy_cache_key $cookie_jwt; # Cache for each access token
proxy_cache_lock on; # Duplicate tokens must wait
proxy_cache_valid 200 10s; # How long to use each response
proxy_ignore_headers Cache-Control Expires Set-Cookie;
}
}
....
Если вы хотите создать больше логики с помощью NJS, например, проверить структуру токена, ваш подход был правильным с использованием NJS с js_set.
js_include oauth2.js; # Location of JavaScript code
server {
listen 80;
location / {
error_page 401 403 =302 http://localhost:9000/login;
auth_request /_oauth2_token_introspection;
proxy_pass http://my_backend;
}
location = /_oauth2_token_introspection {
internal;
js_content introspectAccessToken;
}
функция njs
function introspectAccessToken(r) {
r.subrequest("/_oauth2_send_request",
function(reply) {
if (reply.status == 200) {
var response = JSON.parse(reply.responseBody);
if (response.active == true) {
r.return(204); // Token is valid, return success code
} else {
r.return(403); // Token is invalid, return forbidden code
}
} else {
r.return(401); // Unexpected response, return 'auth required'
}
}
);
}
В
error_page
директива будет работать аналогично. Основываясь на вашем коде, я полагаю, вы уже читали эту статью?
https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/
ICYMI - отличный пост в блоге об этом варианте использования.