PEAR::Authで自動ログイン
しかし、仕事してて調べものしてて、自分のブログがヒットした時の気恥ずかしさと言ったら。。
タイトルに書いたことをしようとしていたのですよ。
で、最初は、「php.iniのsession.cookie_lifetimeを大きくしておけば大丈夫じゃん」って軽く思っていたのですよ。でも、そうすると、デフォルトは「次回からログインを省略する」ってことになってしまって、逆に「ログイン状態を保持しない」って時にどうするの?って問題にぶち当たりまして。
はじめは、session_set_cookie_paramsで、0を指定して、セッションクッキーにしてしまえ!って思ったんですけど、クッキーを発行するのは結局の所Authの中だったりして、知らないうちにsession.cookie_lifetimeで指定された期間保持されるクッキーが発行されてしまったりして。
で、色々調べてみたら、そもそもそのポリシーがいかんと。デフォルトはセッションクッキーにしておいて、明示的に「次回からログインを省略します」と指定されて初めて、その情報を保持すると。当たり前ですね。
で、結局PEAR::Authを使うのは止めて、一から作り直しと。こちらを参考にさせていただきました。
![]() | Webアプリセキュリティ対策入門 ~あなたのサイトは大丈夫? 大垣 靖男 (2006/03/16) 技術評論社 この商品の詳細を見る |
PEAR::Authは、結局内部ではsession関連のPHP関数を使っているので、それを再度作るのはそんなに難しくないと言うことで。処理のイメージはこんな感じで:
- session.cookie_lifetimeは0のままにしておきます。セッションクッキー(ブラウザを閉じた時に破棄されるクッキー)がデフォルト。
- ユーザ管理テーブルにはユーザIDとパスワード、そして、自動ログイン時に用いるキー用のカラムを作っておきます。パスワードとキーはsha1関数をかまして、ハッシュ値にしておきます。
- 毎回、session_start関数でセッションを開始するようにしておきます。これまでは、PEAR::Authがやってくれていました。
- ログイン成功時に「次回からログインを省略します」のチェックがされていると、以下の処理を行います。ちなみに、ログイン成功後は$_SESSION配列にフラグを立てて、ログイン済みとします。各ページではこの配列を参照して、ログイン済みかどうかを判断します。セッション固定化攻撃を避ける意味で、session_regenerate_id関数を呼び出すのも忘れずに。
- 乱数、現在日時などを用いて、推測困難なキーを生成します。
- set_cookieで、上のキーを含むクッキーを発行します。これがユーザのブラウザに格納されます。この時の引数にクッキー保持期間を明示的に指定します。逆に、「次回からログインを省略します」のチェックがされていない場合には、このクッキーを削除する処理を行います。
- このキーをユーザ管理テーブルにも反映させます。このときsha1関数呼びます。
- 次回、サイトにアクセスした際には、クッキーの値を$_COOKIEで参照して、該当するユーザがいないかをキーをsha1関数通して、それをキーに(って分かりにくい)して、ユーザ管理テーブルを参照します。
- 該当するユーザがいれば、そのユーザでログインしたと言うことで、$_SESSION配列にフラグを立てます。これで、自動ログイン完了。キーはこのタイミングで再発行します。
- ログアウトした時には、クッキーを削除します。もちろん、session_destroyも。
楽しようとしてライブラリ使うと、今度は自由が利かないと言うことで。