Как настроить редирект на определенный URL в Nginx при неудачной попытке базовой авторизации?

Здравствуйте! 

В конфигурации Nginx, где используется базовая авторизация, после неудачной попытки входа пользователь перенаправляется на страницу с ошибкой 401 (401.html). Как можно изменить это поведение так, чтобы пользователя перенаправляло на другой URL в случае неверного ввода данных или закрытия окна ввода? В данный момент вместо редиректа отображается страница 401.html, и я не нашел решения для реализации редиректа на другой адрес. 

Прилагаю текущую конфигурацию:

<pre><code class="bash">server {
    listen 80;
    location / {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/conf.d/htpasswd;
        proxy_pass http://url:80;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection $connection_upgrade;
        proxy_cache off;
        error_page 401 /error/401.html;
    }
    location = /error/401.html {
        root /usr/share/nginx/html;
        auth_basic off;
    }
}</code></pre>
  • 16 января 2025 г. 14:54
Ответы на вопрос 2
Чтобы настроить редирект на определенный URL в Nginx при неудачной попытке базовой авторизации, не получится сделать это напрямую с помощью кода статуса 401, поскольку браузеры обрабатывают статус 401 особым образом - они показывают окно ввода логина и пароля и не выполняют редиректы.

Однако, вы можете использовать некоторую хитрость: вместо предоставления страницы с ошибкой, вы можете обрабатывать статус 401 через Lua (если у вас установлен модуль ngx_http_lua_module) или использовать JavaScript-редирект на стороне клиента.

***Способ 1: Rеdirект через JavaScript (передача страницы 401)***

Это будет простейший способ. Вместо редиректа на простой HTML файл с ошибкой, мы создаем страницу с JavaScript, который будет перенаправлять нас на нужный URL.

Создайте файл `/usr/share/nginx/html/error/401.html` с содержимым:

```html
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="refresh" content="0; URL='https://example.com/your_redirect_url'" />
    <title>Redirecting...</title>
</head>
<body>
    <p>Redirecting you to <a href="https://example.com/your_redirect_url">this page</a>.</p>
</body>
</html>
```

Затем отредактируйте вашу конфигурацию Nginx, чтобы она оставалась прежней:

```nginx
server {
    listen 80;
    location / {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/conf.d/htpasswd;
        proxy_pass http://url:80;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection $connection_upgrade;
        proxy_cache off;
        error_page 401 /error/401.html;
    }
    
    location = /error/401.html {
        root /usr/share/nginx/html;
        auth_basic off;
    }
}
```

***Способ 2: Использование Lua***

Если у вас есть Lua модуль и вы хотите делать перенаправление на серверной стороне, конфигурация будет выглядеть так:

```nginx
server {
    listen 80;
    
    location / {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/conf.d/htpasswd;
        
        # Добавьте Lua обработчик
        error_page 401 = @handle_401;
        
        proxy_pass http://url:80;
        proxy_http_version 1.1;
        ... # остальные директивы
    }
    
    location @handle_401 {
        return 302 https://example.com/your_redirect_url;
    }
}
```

Таким образом, при неудачной попытке авторизации пользователь будет перенаправлен на указанный URL. Выберите тот способ, который больше соответствует вашим требованиям и окружению.
location / {
    ....
    error_page 401 = @fallback;
}

location @fallback {
    proxy_pass http://url_needed:port;
    # Целый локейшен под все что душе угодно
}
Похожие вопросы