tl;dr
えのかわです。Nginx で特定パスのみ Basic 認証を有効化したい場面に遭遇したので備忘録として残します。前提として、Nginx の Backend には php-fpm が存在するものとします。
なぜmapか
ngx_http_map_module
を利用することで、シンプルに条件を記述することが可能です。パス毎に location
を記載するのも一つの手段ですが、期待する挙動とならずに苦戦してしまい map モジュールを使うことにしました。(おい
nginx.conf
にmapを定義
まずは /etc/nginx/nginx.conf
に map を定義します。今回は /sample/
もしくは /admin/
配下にリクエストがあった際に Basic 認証を有効化させるものとします。
map $request_uri $auth { default off; ~^/sample/.* "Basic Authentication"; ~^/admin/.* "Basic Authentication"; }
~
は正規表現の利用を宣言しています。前述のドキュメントにも下記の様に正規表現の記載があります。
A regular expression should either start from the “~” symbol for a case-sensitive matching, or from the “~*” symbols (1.0.4) for case-insensitive matching. A regular expression can contain named and positional captures that can later be used in other directives along with the resulting variable.
ハマったのが、map を定義する conf です。/etc/nginx/conf.d/
配下の default.conf
に定義しようとすると、下記の様にエラーが発生しました。
2019/11/25 15:01:35 [emerg] 1#1: "map" directive is not allowed here in /etc/nginx/conf.d/default.conf:8 nginx: [emerg] "map" directive is not allowed here in /etc/nginx/conf.d/default.conf:8
こちらも前述のドキュメントに丁寧に Directives が記載されていますね。nginx.conf
というよりは、http Directive に記載しましょう。が正しいですね。ちゃんとドキュメントを読みましょう。はい。(スミマセン
Syntax: map string $variable { ... } Default: — Context: http
default.conf
にauth_basic
を定義
下記の様に Basic 認証の設定を記載します。
location ~ \.php$ { root /var/www/html/public; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; + auth_basic $auth; + auth_basic_user_file /etc/nginx/.htpasswd; }
キモは auth_basic
の値が $auth
となっている点です。nginx.conf
で定義した map の値を参照して振る舞います。ngx_http_auth_basic_module
の仕様上、auth_basic
の値が off
の場合は Basic 認証をキャンセルします。先ほど定義した map には default off;
と記載されているため、/sample/
もしくは /admin/
配下へのリクエストがあった場合にのみ Basic 認証が有効化され、それ以外のパスへリクエストがあった場合は Basic 認証をキャンセル(off
)します。
Enables validation of user name and password using the “HTTP Basic Authentication” protocol. The specified parameter is used as a realm. Parameter value can contain variables (1.3.10, 1.2.7). The special value off allows cancelling the effect of the auth_basic directive inherited from the previous configuration level.
余談
location Context で if を利用することが可能ですが、Nginx としては推奨していないようです。Nginx 公式が If Is Evil
(if Directive は悪)と謳っていることから、信憑性は高いでしょう。Qiita やその他ブログを漁ったところ、map ではなく if で判定している内容もちらほら見られたので、気をつけようと思いました。
まとめ
ちゃんと公式ドキュメントは読みましょう。(戒め