ngx_http_userid_module の uid_got/uid_set と cookie に書き込まれる uid について
ngx_http_userid_module を使うと nginx でクライアントを識別するための 識別子 を cookie に焼くことができる。
また、cookie に書き込んだあたいは $uid_got/$uid_set の組み込み変数で参照可能でログなどに記録することができる。
例えば、以下のような conf で nginx を起動し、適当にアクセスした場合のログを見てみる
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; userid on; userid_name uid; userid_path /; userid_expires max; log_format main "time:$time_local\t" 'req:$request\t' 'cookie:$http_cookie\t' 'set_cookie:$sent_http_set_cookie\t' 'uid_got:$uid_got\t' 'uid_set:$uid_set'; access_log /var/log/nginx/access.log main; sendfile on; include /etc/nginx/conf.d/*.conf; }
ログはこちらになる
time:21/Aug/2020:03:16:37 +0000 req:GET / HTTP/1.1 cookie:- set_cookie:uid=rBEAAl8/PJUlwAAGAwMEAg==; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/ uid_got:- uid_set:uid=020011AC953C3F5F0600C02502040303
set_cookie と uid_set(初回はuid_set に値が入って次回以降はuid_gotに値が入る)を見る
set_cookie:uid=rBEAAl8/PJUlwAAGAwMEAg==; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/ uid_set: uid=020011AC953C3F5F0600C02502040303
cookie に書き込まれている識別子は rBEAAl8/PJUlwAAGAwMEAg==
だが uid_set で参照できる識別子は 020011AC953C3F5F0600C02502040303
で一致しない。
この辺りを眺めるとどうやら uid_set に対してごにょごにょした値が cookie にセットされるようだった。
uid_set の値から cookie に書き込んでいる値への変換処理はおそらくこの辺り。 ソースコードは正直何やっているのかちゃんと追えなかったのでメーリングリストに書いてある処理で cookie の値から uid_set の値に変換してみる
[1] pry(main)> require 'base64' => true [2] pry(main)> Base64.decode64("rBEAAl8/PJUlwAAGAwMEAg==").unpack("L*").map{|a| sprintf("%08X", a)}.join.upcase => "020011AC953C3F5F0600C02502040303"
ちゃんと変換できた。 sprintf("%08X", a)
が味噌で8桁で揃えないと先頭が0の場合にデータがかけて微妙に違うデータになる。
これは uid_set が uint32_t で定義されているからだと思う
逆のことをやれば、 uid_set から cookie の値に変換することもできる。
[4] pry(main)> Base64.encode64("020011AC953C3F5F0600C02502040303".downcase.scan(/.{1,8}/).map{|a| a.to_i(16)}.pack("l*")) => "rBEAAl8/PJUlwAAGAwMEAg==\n"