「IDとパスワードを使ってログインする」というステップを省略するために、PC用のWeb上のサービスやシステムでは Cookie を使うことがよくあります。
ところがPCと違ってケータイは、Cookieに対応していない端末が多数を占めます。
そのため、ケータイ向けのWeb上のサービスやシステムを作る際、ログインを簡略化するために、「サブスクライバID」とか「端末シリアル番号」とか「固体識別情報」とか呼ばれるものを使うことが、よくあります。
これは、それぞれの携帯電話個別に、電話番号とは別に割り振られた固有のIDのようなもので、多分 mixi の「かんたんログイン」とかも、これを取得して認証しているはず。
DoCoMo と Softbank は未確認ですが、少なくとも au の場合は、機種変更をしても、この番号は引き継がれるので、ケータイ所有者個人を識別するためにはかなり有効です。
ただし、どこのキャリアかは知りませんが、「解約して使われなくなった端末識別情報が、別の誰かに割り振られることがある」なんてことを聞いたことがあるので、この端末識別情報に頼りすぎたログイン認証システムは、安全ではないかもしれないことも付記しておきます。
DoCoMo の iモード端末の固体識別情報
html の a要素や form要素に utn属性 をつけることによって、そのリンクや送信ボタンをクリックした際に、サーバーに固体識別情報が送信されます。
なお、送信される前に端末側には「固体識別情報を送信しますか?」みたいな確認ダイアログが表示され、同意した場合のみ送信されます。
<!-- a要素の場合 -->
<p><a href="http://www.abe-tatsuya.com/login.cgi" utn>ログイン</a></p>
<!-- form要素の場合 -->
<form method="POST"
action="http://www.abe-tatsuya.com/login.cgi" utn>
<input type="submit" value="ログイン" />
</form>
本当は valid な xhtml にするために、utn="utn" としたいところなんですが、ケータイというのは機種ごとに仕様が異なっていたりして、「utn="utn"」という書き方だと正常に動作してくれない機種なんかもありそうで怖いので、DoCoMo の utn属性の説明ページの通りに書いています。
全機種の動作確認ができる機会も、まずないですし……。
このエントリーのコメントでご指摘頂いた通り、i-mode HTML/XHTML 比較表を見ると、「utn="utn"」という書き方で大丈夫なようです。
コメント頂いたyurikoさん、ありがとうございました。
で、サーバー側に送られてくる固体識別情報はどこに含まれているかというと、User-Agent ヘッダに含まれています。
非FOMA端末の場合、固体識別情報を含んだ User-Agent は以下のようになります。
DoCoMo/1.0/X503i/c10/ser***********
「ser***********」の「***********」の部分には、11桁の英数字が入り、これが固体識別情報に当たります。
perl でこれを取得しようとすると、以下のような感じでしょうか(普段自分が使ってるソースは、他のサブルーチンから渡される変数を色々使ってて、ブログに掲載しても可読性が低いと思われるので新たに書きました。以下のソースは動作確認を全くしてません)。
if($ENV{'HTTP_USER_AGENT'} =~ /^DoCoMo\/1\.0\/.*\/(ser\w{11})$/){
#-- 固体識別情報を変数に代入
$mobile_id = $1;
}
FOMA端末の場合は「携帯電話の製造番号」と「FOMAカードの製造番号」の二種類の固体識別情報が取得できます。
「携帯電話の製造番号」の方は、機種変更をしたら変わってしまうと思うんですが、「FOMAカードの製造番号」の方は、多分機種変更をしても、FOMAカードが同一であれば変わらないはず。
FOMA端末の、固体識別情報を含んだ User-Agent は以下の通り。
DoCoMo/2.0 YYYY(c10;serXXXXXXXXXXXXXXX; iccxxxxxxxxxxxxxxxxxxxx)
「serXXXXXXXXXXXXXXX」の部分が携帯電話の製造番号で、「XXXXXXXXXXXXXXX」には15桁の英数字が入ります。
「iccxxxxxxxxxxxxxxxxxxxx」の部分がFOMAカードの製造番号で、「xxxxxxxxxxxxxxxxxxxx」には20桁の英数字が入ります。
用途にもよりますが、基本的には FOMAカードの製造番号を取得した方が便利ですかね。
FOMAカードの製造番号を取得する perl のスクリプトは以下(上の同じく、以下のソースは動作確認を全くしてません)。
if($ENV{'HTTP_USER_AGENT'} =~ /^DoCoMo\/2\.0 .*; (icc\w{20})\)$/){
#-- 固体識別情報を変数に代入
$mobile_id = $1;
}
au の EZweb 端末のサブスクライバID
au の場合は、自動的にサブスクライバIDと呼ばれる X_UP_SUBNO ヘッダを、サーバーに送信しています。
ただし、ユーザー側がこのヘッダを「通知しない」という設定にしている場合は、送信しません。
通知設定に関しては、au 公式サイトのお知らせにあります。
サーバーに送信される X_UP_SUBNO ヘッダは、以下のようなフォーマットになっています。
xxxxxxxxxxxxxx_**.ezweb.ne.jp
最初の「xxxxxxxxxxxxxx」の部分が14桁の数字で、端末固有の番号にあたるようです。
※参考: モバイルCGI研究(EZweb編)環境変数リファレンス [CGIぽん]
サブスクライバIDを取得する perl スクリプトは以下の通り(同様に以下のソースは動作確認を全くしてません)。
if($ENV{'HTTP_X_UP_SUBNO'} =~ /^(\d{14})_\w{2}\.ezweb\.ne\.jp$/){
#-- サブスクライバIDを変数に代入
$mobile_id = $1;
}
Softbank 端末の端末シリアル番号
Softbank の端末の場合、ユーザーが「ユーザーID通知」または「製造番号通知」の設定を on にしていれば、端末シリアル番号というものが User-Agent に含まれます。
端末の世代によって、フォーマットが異なってややこしいですが、ソフトバンクの公式サイトのユーザーエージェントについての説明によると、以下のようなパターンがあるらしいです。
#-- SoftBank 6-5 Series
J-PHONE/4.0/J-SH51/SN************ SH/0001a Profile/MIDP-1.0 Configuration/CLDC-1.0
Ext-Profile/JSCL-1.1.0
#-- SoftBank 3G Series (Vodafone時代の端末)
Vodafone/1.0/V904SH/SHJ001/SN************ Browser/VF-NetFront/3.3 Profile/MIDP-2.0
Configuration/CLDC-1.1
#-- SoftBank 3G Series (Softbank時代の端末)
SoftBank/1.0/910T/TJ001/SN************ Browser/NetFront/3.3 Profile/MIDP-2.0
Configuration/CLDC-1.1
「SN************」の部分が端末シリアル番号で「************」には11~15桁の英数字が入るようです。
端末シリアル番号を取得する perl スクリプトは、ちょっといいかげんですが以下のような感じ(同様に以下のソースは動作確認を全くしてません)。
if($ENV{'HTTP_USER_AGENT'} =~ /^(J\-PHONE|Vodafone|Softbank)\/.*\/(SN\w{11,15}) .*/){
#-- 端末シリアル番号を変数に代入
$mobile_id = $2;
}
端末識別情報に頼りすぎないこと
ログイン認証を端末識別情報に依存しすぎたせいで、「機種変更したらログインできない」なんていう事態に陥ったサービスを知っています。
また、たまたま携帯事業者側の都合で、全く同じ番号の端末識別情報が複数の端末に割り振られた、なんてケースも聞いたことがあります。
ケータイは文字入力が不便なインターフェイスなので、ログインの簡略化のために端末識別情報を使うのは、ユーザーの利便性向上のためにも、良いことだとは思うのですが、認証をこれだけに頼るのは、ちょっと危険かもしれません。