デバイスを推定する
webサイトではユーザがどのようなデバイスでアクセスしているかを判断しなくてはならない場合があります。
デバイスの種類を推定することは、よりそのデバイスに最適化されたページを生成、表示させる為にとても重要な要素ですよね。
そこで今回はデバイスを推定するために使える情報をまとめてみました。
この記事で言うデバイスとは機種までではなく、スマートフォンかPCかとか、iOSかandoridかとかなどの「種類」のことです。
ユーザーエージェント
ブラウザには自分が何者かを伝える為に名刺みたいな情報を持っています。この情報はクライアント側でも、サーバ側でも取得することができます。
取得する方法は以下の様になります。
//サーバ側(php)
$userAgent = $_SERVER['HTTP_USER_AGENT'];
//クライアント側(javascript)
var userAgent = navigator.userAgent;
ブラウザの種類、OS、機種名等が取得できるので、情報としてはとても頼もしいデス。
しかしこのユーザーエージェントはブラウザがサーバを送る時に内容を任意なものに偽装できてしまいます…。
たとえばPCのブラウザでもiPhoneからアクセスしたようなユーザーエージェントに偽装することが可能です。その為サーバ側で取得できるユーザエージェントは正確性を保障できません。
一方クライアント側でのユーザーエージェントは偽装がしにくいので、信頼性が高いと言えます。
もし信頼度の高いデバイス推定を行いたいのであれば、クライアント側で取得した方がいいのではないかと思います。
ユーザーエージェントは文字列なので、正規表現で目的の文字があるかどうか(たとえばandroidという単語が入っているか)を判断しなくてはならないです。
その為、事前にそのデバイスでユーザーエージェントがどのように取得できるのかを知らなければならないという面倒な点はありますね。
また、仕様の変更などでユーザーエージェントが変更になる場合もあるので、それに合わせて判別プロセスも変化させる必要が生じるかもしれません。
ユーザーエージェントの種類が多くなってしまうスマートフォンに関しては公式ページを確認するのが良いと思います。ちなみにdocomoのサイトはユーザーエージェントの確認がしにくいです。
- au Android™ 技術情報 > User Agent
- http://www.au.kddi.com/developer/android/kishu/ua/
- Softbankスマートフォンサービス開発支援サイト 技術情報 端末情報
- https://www.support.softbankmobile.co.jp/partner/smp_info/smp_info_search_t.cfm
- docomo 開発者向け情報 / 作ろうスマートフォンコンテンツ / スペック一覧
- https://www.nttdocomo.co.jp/service/developer/smart_phone/spec/
画面の大きさ
画面の大きさはデバイスを推測するのに非常に役に立ちます。なぜなら物理値だからです。昨今ではさまざまな画面サイズが存在し、混乱の極みだが、物理的な画面の大きさは良くあるようにインチで表せます。
画面の大きさからインチ数を割り出してしまえば、それがスマートフォン(4inch~7inch未満)なのか、ファブレット(7inch~10inch未満)なのか、タブレット(おおよそ10inch程度)なのか、PC(おおよそ13inch以上)なのかを類推することはできます。
この情報も改ざんが出来ない訳ではないですが、ユーザーエージェントを偽装するよりはるかに偽装される場合が少ないかと思います。
この情報はクライアント側から取得するのが基本。ブラウザはサーバ側に画面の大きさの情報は送らないので取得は出来ないです。(はず)。
OSの種類
javascriptではブラウザが動いている環境のOSを取得することが可能です。
//クライアント側(javascript)
var os = navigator.platform;
ブラウザはサーバにこの情報を送ることはないので、基本的にサーバからクライアントのOSの種類を取得することはできません。
この情報は偽装が困難なので、信頼性が高いと思います。前述したようにwindowsでiphoneのように見せかける為にユーザーエージェントを偽装したとしても、navigator.platformでOSを取得すると「win32」となります。
その為、この情報でユーザエージェントが偽装されているかどうかを判断することが可能になります。
サポートしている機能
ブラウザはそれぞれにサポートしている機能が異なる部分があります。最新の機能であればあるほどブラウザによって実装はまちまち。その状況を逆手にとって、実装されている/いないを判断することで、そのデバイスを推測する材料にすることは可能です。
プロパティやメソッドが存在しているかどうかを判断するわけです。
しかし、スマートフォンでも複数のブラウザ選択肢があるため、特定のブラウザでデバイスを推測することは困難と言わざるを得ないです。
ただ、サポートされていない機能をエスケープしたり、他の情報と組み合わせてより深い条件分岐を行う事は出来るかと思います。
具体的にはICanUseなどで実装状況を確認して、プロパティやメソッドを条件式で判断するという方法になるでしょうね。
ブラウザの状況が変わると、判断に使えなくなったりするので、あまり使いたくない手ではあります。
IP(サーバ名)
アクセスしているIPを取得するのも一応デバイスを推定する材料にはなります。これはスマートフォンなどの電話機能が備わっているデバイスのみの話。
スマートフォンでwifiなどではなく、電話会社の電波で通信していた場合、それはdocomoやauやsoftbankのサーバを経由してくることになるので、IPから正引きしてサーバ名を得れば、docomoやauやsoftbankなどの名前を確認できるはずです。
一昔前、まだガラケーが全盛だった時代は、このIP判断が非常に強力なデバイス判断方法だったです。(個体識別を合わせるとほぼ100%ガラケーだということが判った)
デバイス判断のサブ的要素としては現在も使えるのではないかと思います。
まとめ
おそらくクライアント側で取得したOSを基準に、クライアント側で取得したユーザーエージェント、画面の大きさでデバイスを推定するのが最も手軽で信頼性が高い方法だと思います。
OSがlinuxで画面の大きさが15inchならそれはPCだろうし、5inchならたぶんandroidでしょう。OSがiOSならiPhoneかiPadだろうし、画面サイズが4inch程度ならiPhone5以前の機種でしょう。
最後にユーザエージェントで答え合わせ的に判断すると、かなり正確にデバイスを判別することができるかなと思います。
ただ、@MINOは知らないのだが、navigatorオブジェクトの内容を偽装できる方法があるとしたら、信頼性は担保できなくなりますね。これの偽装はかなり難易度が高いと思うのですが、もし偽装できるとしたら、なんのために偽装したいのかがよくわからないデス。
偽装メリットはほとんどないはずだ…が…。
こわやこわや。