はじめに
はじめまして!LetroStudio開発チームの小嶋です!
2023年5月にGoogle ChromeのUser Agentの一部文字列が削減されました。
代わりにUser-Agent Client Hintsという新しいパラメータが追加されています。
今回はUser-Agent Client Hintsを使ってNginxでブラウザを判定してみたのでまとめます。
User Agentの確認
まず現在のUser Agentを確認してみました。
Windows 10 Chrome
1 |
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 |
Windows 11 Chrome
1 |
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 |
Windows 10 Edge
1 |
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.76 |
Windows 11 Edge
1 |
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.69 |
ブラウザマイナーバージョンが0だったり、Windows 11でもOSバージョンが10.0と表示されていて、正しいブラウザのマイナーバージョン・OSバージョンが取得できなくなっています。この部分はブラウザのバージョンが更新されても変更されずに固定化されるようです。
User Agent Client Hintsの確認
Windows 10 Chrome
1 2 3 4 5 6 7 8 9 10 |
Sec-Ch-Ua: "Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116" Sec-Ch-Ua-Arch: "x86" Sec-Ch-Ua-Bitness: "64" Sec-Ch-Ua-Full-Version: "116.0.5845.180" Sec-Ch-Ua-Full-Version-List: "Chromium";v="116.0.5845.180", "Not)A;Brand";v="24.0.0.0", "Google Chrome";v="116.0.5845.180" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Model: "" Sec-Ch-Ua-Platform: "Windows" Sec-Ch-Ua-Platform-Version: "10.0.0" Sec-Ch-Ua-Wow64: ?0 |
Windows 11 Chrome
1 2 3 4 5 6 7 8 9 10 |
Sec-Ch-Ua: "Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116" Sec-Ch-Ua-Arch: "x86" Sec-Ch-Ua-Bitness: "64" Sec-Ch-Ua-Full-Version: "116.0.5845.142" Sec-Ch-Ua-Full-Version-List: "Chromium";v="116.0.5845.142", "Not)A;Brand";v="24.0.0.0", "Google Chrome";v="116.0.5845.142" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Model: "" Sec-Ch-Ua-Platform: "Windows" Sec-Ch-Ua-Platform-Version: "15.0.0" Sec-Ch-Ua-Wow64: ?0 |
Windows 10 Edge
1 2 3 4 5 6 7 8 9 10 |
Sec-Ch-Ua: "Chromium";v="116", "Not)A;Brand";v="24", "Microsoft Edge";v="116" Sec-Ch-Ua-Arch: "x86" Sec-Ch-Ua-Bitness: "64" Sec-Ch-Ua-Full-Version: "116.0.1938.69" Sec-Ch-Ua-Full-Version-List: "Chromium";v="116.0.5845.141", "Not)A;Brand";v="24.0.0.0", "Microsoft Edge";v="116.0.1938.69" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Model: "" Sec-Ch-Ua-Platform: "Windows" Sec-Ch-Ua-Platform-Version: "10.0.0" Sec-Ch-Ua-Wow64: ?0 |
Windows 11 Edge
1 2 3 4 5 6 7 8 9 10 |
Sec-Ch-Ua: "Chromium";v="116", "Not)A;Brand";v="24", "Microsoft Edge";v="116" Sec-Ch-Ua-Arch: "x86" Sec-Ch-Ua-Bitness: "64" Sec-Ch-Ua-Full-Version: "116.0.1938.69" Sec-Ch-Ua-Full-Version-List: "Chromium";v="116.0.5845.141", "Not)A;Brand";v="24.0.0.0", "Microsoft Edge";v="116.0.1938.69" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Model: "" Sec-Ch-Ua-Platform: "Windows" Sec-Ch-Ua-Platform-Version: "15.0.0" Sec-Ch-Ua-Wow64: ?0 |
今までのUser Agentと比較すると項目ごとに分かれているので、値がシンプルで取得しやすくなっています。
Sec-Ch-Uaにブラウザの種類とバージョンが集約されています。
Sec-Ch-Ua-Mobileはモバイルフラグです。
Sec-Ch-Ua-PlatformとSec-Ch-Ua-Platform-VersionはOSとOSバージョンです。
Sec-Ch-Ua-Platform-Versionですが、Windows 10では「10.0」、Windows 11では「15.0」と表示されました。Windows 11以降は13以上の値が表示されるようです。
参考:User-Agent クライアント ヒントを使用してWindows 11と CPU アーキテクチャを検出する
Nginxでブラウザのユーザーエージェントを判定する
https://localhost/test/ にアクセスしたら、ブラウザを判別して、ブラウザごとに別のページにリダイレクトしてみます。
例)chromeでアクセスしたとき
https://localhost/test/ → https://localhost/test/<ブラウザ名>.html にリダイレクトしました。
設定はこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
・・・ http { ・・・ add_header Accept-CH 'Sec-CH-UA-Arch, Sec-CH-UA-Model, Sec-CH-UA-Platform-Version, Sec-CH-UA-Full-Version-List, Sec-CH-UA-Wow64'; ・・・ map $http_sec_ch_ua$http_user_agent $html { default index.html; ~\"Google\sChrome\" chrome.html; ~\"Microsoft\sEdge\" edge.html; ~Firefox|FxiOS firefox.html; ~^(?=.*Safari)(?!.*Chrome)(?!.*CriOS)(?!.*Firefox)(?!.*FxiOS).*$ safari.html; } ・・・ server { location ~ ^/test/$ { rewrite ^(.*)$ $1$html redirect; } } } ・・・ |
大きく3つの設定をしました。
1.User Agent Client Hintsを取得する設定
User Agent Client Hintsを取得するためには、add_header Accept-CHを追加する必要があります。
1 |
add_header Accept-CH 'Sec-CH-UA-Arch, Sec-CH-UA-Model, Sec-CH-UA-Platform-Version, Sec-CH-UA-Full-Version-List, Sec-CH-UA-Wow64'; |
2.ブラウザを判別する処理
ここではmapディレクティブを使ってブラウザを判別して、リダイレクト先のHTMLファイルを指定します。
UserAgent Client Hintsの対応状況がブラウザによって異なるため、UserAgent Client HintsとUserAgentを結合して判定することにしました。
$http_sec_ch_uaでUser Agent Client Hintsが使えます。
$http_user_agentはUser Agentです。
Safariを判定するときだけ複雑ですが、
「Safari」を含む かつ Chrome / CriOS / FireFox / FxiOS を含まない
という条件になっています。
1 2 3 4 5 6 7 |
map $http_sec_ch_ua$http_user_agent $html { default index.html; ~\"Google\sChrome\" chrome.html; ~\"Microsoft\sEdge\" edge.html; ~Firefox|FxiOS firefox.html; ~^(?=.*Safari)(?!.*Chrome)(?!.*CriOS)(?!.*Firefox)(?!.*FxiOS).*$ safari.html; } |
3.ブラウザごとのページに別サイトにリダイレクトする処理
/test/でアクセスしたときに、ブラウザごとのHTMLファイルにリダイレクトしています。
1 2 3 4 5 |
server { location ~ ^/test/$ { rewrite ^(.*)$ $1$html redirect; } } |
locationの中ではmapディレクティブが使えないようです。
初めはifで書こうと思ったのですが、nginxのifは通常のプログラミング言語の条件分岐と異なっているようでした。
予期しない動作の原因になることがあるため今回は使いませんでした。
まとめ
User Agent Client Hintsを利用してNginxでブラウザ判定してみました。
User Agentは過去のブラウザ戦争で複雑化しすぎていたので、それと比較するとUser Agent Client Hintsはとてもシンプルになっているため判定しやすいと思いました。
今回は使いませんでしたがモバイル判定も簡単です。
現時点ではSafariとFirefoxが非対応です。
早く対応してシンプルなブラウザ判定ができると良いですね。