Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

auth_requestをするときは変数に注意

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;
}

定数を定義できればこんな問題も起きなかったはずです。定数がほしいですね。

というか、評価順が直感的でなくて厄介です。動作から推察するに、おそらく次のような評価順です。

  1. /private をすべて評価
  2. $upstream_server が private になる
  3. /auth/is_logged_in を評価
  4. $upstream_server が auth_server になる
  5. ログインが確認できたら/private の proxy_pass を見てリバースプロキシ

直感的には「auth_requestが評価されたらただちにログイン判定」になりそうなものですが。なんじゃこりゃ…