3 時間くらいハマったのでメモしておきます。
ハマった状況
以下のようなコードを書いたら、変数が上書きされてうまくいきませんでした。
location /private { auth_request /auth/is_logged_in; resolver 127.0.0.11; set $upstream_server private; proxy_pass http://$upstream_server; } location = /auth/is_logged_in { resolver 127.0.0.11; set $upstream_server auth_server; proxy_pass http://$upstream_server; internal; }
上の設定では、/private の proxy_pass が/auth/is_logged_in のステータスがいくつかに関わらず常にhttp://private
ではなくhttp://auth_server
となります。なんということでしょう…Nginx の変数の仕様は複雑怪奇ですね。
解決策
そもそも同じ変数名にしなければ良いです。
location /private { auth_request /auth/is_logged_in; resolver 127.0.0.11; set $private_server private; proxy_pass http://$private_server; } location = /auth/is_logged_in { resolver 127.0.0.11; set $auth_server auth_server; proxy_pass http://$auth_server; internal; }
定数を定義できればこんな問題も起きなかったはずです。定数がほしいですね。
というか、評価順が直感的でなくて厄介です。動作から推察するに、おそらく次のような評価順です。
- /private をすべて評価
- $upstream_server が
private
になる - /auth/is_logged_in を評価
- $upstream_server が
auth_server
になる - ログインが確認できたら/private の proxy_pass を見てリバースプロキシ
直感的には「auth_requestが評価されたらただちにログイン判定」になりそうなものですが。なんじゃこりゃ…