「次回から自動でログイン」の実装考察

ログインする必要があるWebサービスを構築する上でよく見る「次回から自動でログイン」の実装について考察してみようと思う。

クライアント側に記憶させる情報

次回からログインを省略するということは、クライアント側に何らかのユーザ情報を覚えさせておく必要があると思う。だから、Cookieを使うのは必須で、ここに何を登録するか?というのが一番重要だと思う。ユーザ情報を登録するんだから、以下の二つは必要

  • ユーザを識別できる情報(ユーザIDとか、ユーザ名とか)
  • それが本人と識別できる情報(パスワード)

ここで、重要になるのがパスワードだと思う。単純にログインするときに使用するパスワードを使ってしまうと、Cookieにパスワードをそのまま入れることと等しくなるので、これはセキュリティ上よろしくない。Cookieなんて見ようと思えば誰でも見れる場所であって、そこにパスワードを入れるなんてもってのほかだと思う。

じゃあ、どうするかって考えると、普通に思いつくのがワンタイムパスワードだと思う。Cookieからログイン処理を行うたびに新たなワンタイムパスワードを作成して、Cookieに新たに登録する。こうすることで、Cookieからログインした際のパケットを見られたとしても、ログイン後にすぐにそのパスワードは変更されてしまうため、セキュリティ上も問題ないと思う。万全を期すならユーザ情報すらもワンタイムとして作成すべきだと思うけど、パスワードのみの場合とあまり堅牢性は変わらないし別にそこまでやる必要も無いのかと思う。

情報を保持する期間

ずっとCookie上に保存し続けるのも僕としてはありなのかと思う。まず、CookieがあるPCからアクセスされたということは、本人であると考えて問題ないんじゃ無いかと思う。複数人が使うPC上で「次回から自動でログイン」にチェックを入れるということは、他の人からアクセスされても問題ないと思っていいんじゃないかな。ただし、大体は他の人にPCをさわらせる気は無かったけど、何らかの事情で他の人の手にPCが渡ってしまってアクセスされるってことも考えられるから、ベストは1週間から1ヶ月程度で消すのが一般的だと思う。Cookieを消すということは自動でログインすることが出来ないので、ユーザから見ると利便性は下がる。ここの期間は各サービスのログイン情報の重要性からケースバイケースで考えるべき点だと思う。

Cookieを消すタイミング

ログアウト処理を行ったときにCookieを消すか否か。これは結構悩ましい。ユーザはその時に使用する操作が完了したからログアウトを行っただけかもしれない。それなのに、Cookieを消してしまうとログイン処理を行わなくていいつもりだったユーザに対してログイン処理を行わせる必要性が出てくる。これはユーザは意図せぬ処理だからちょっとしたストレスになるかもしれない。

けど、ちょっと考えてみるとログアウト処理を行った際にCookieを消さないと、Cookieが削除される処理が行われるタイミングがTimeoutによる削除しか行われなくなってしまう。情報を保持するタイミングを無期限でよいと考えてしまった場合、そのPCからのアクセスはいつでも誰でもアクセスできてしまうことになる。これがよいかどうかは各ユーザによるといえばよるが、僕はアマリよろしくないと思う。なので、ログアウト処理を行った際にCookieは消すべきだと思う。まぁ、ユーザ操作でCookieを削除することは可能だからそこまで考える必要も無いのかもしれないけど。

実装

上記を踏まえて実装してみたとする。適当に書いてるから参考程度に・・・。

<?php

function logincheck() {
    /* ログイン情報はセション変数で管理しているものとする */
    $user_info = $_SESSION['login_info'];

    /* 値が入ってたらログイン中とする */
    if( !$user_info ) {

        /* Cookieからログイン情報を取得する */
        $login_info = $_COOKIE['login_info'];

       /* Cookieの値が入ってたら次回から自動でログインをチェックされたものと判断 */
       if( !$login_info ) {

           /* ワンタイムパスワードとIDからユーザ情報を取得 */
           $user_info = get_user_info($login_info);

           /* ワンタイムパスワードを作成 */
           $one_pass = md5( $user_info . rand() );

           /* あらたなCookieを登録 */
           setcookie("login_info", $user_info->id . "," . $one_pass);
       }
    }

    /* ユーザ情報返答してNULLなら未ログインとして処理 */
    return $user_info;
}

?>

感想

たぶんどこもこんな感じの考え方で実装してるんじゃないかな。これなら手軽にセキュアに成るのかと思う。突込みがある方はよろしくお願いします。