第11回 会員認証 - OOP講座

PHP 中級 講座

がる先生のOOP講座

Lecutures on PHP

第11回 会員認証 (その1)

 このエントリーをはてなブックマークに追加

会員認証

がる先生前回は、ざっくりしたイメージを把握していきました。
このままですと「絵に描いた餅」のままなので。
今回は、餅米を蒸して、搗いて、食せるところまで進めてみたいと思います。

まずは、ログイン(authentication)と認証(authorization)部分を、それぞれ実装して…みる前に、PHPでセッション関数を使う時の「お作法へのご提案」を一つ、書いておきます。

list 1

初期処理

  1  // セッションID作成のためのベース
  2  // その1
  3  
ini_set('session.entropy_file''/dev/urandom');
  4  
ini_set('session.entropy_length''16');
  5  
// その2
  6  
ini_set('session.entropy_file''/dev/random');
  7  
ini_set('session.entropy_length''16');
  8  
// その3
  9  
ini_set('session.entropy_file''/proc/net/dev');
 10  
ini_set('session.entropy_length''2048');
 11  
// XXX 上述その1~3は、一つ好きなものをチョイスしてください
 12  
 13  // ハッシュ関数の指定
 14  
ini_set('session.hash_function''1');
 15  
// または
 16  
ini_set('session.hash_function''sha-256');
 17  
// XXX 上述は、2行のうちいずれか片方を。5.3未満なら上を選んでください
 18  
 19  //
 20  
ini_set('session.use_only_cookies''1');
 21  
ini_set('session.cookie_lifetime''0');
 22  
ini_set('session.cache_expire'セッション寿命の分数:デフォルトは180);
 23  
ini_set('session.use_trans_sid''0');
 24  
ini_set('session.name'お好みのセッション名:デフォルトは'PHPSESSID');
 25  
 26  
// バッファリングの開始
 27  
ob_start();
 28  
 29  
// セッション開始
 30  
session_start();

がる先生別段、特にini_setの部分は、php.iniで設定できるならそちらでもよいのですが、とりあえずプログラム側の先頭でしっかりと指定しておくと、異なる環境でも比較的心安良かにセッション関数群を使う事ができるようになります。
セッションは原則「漏れがない」ように、共通の場所で開始しておきましょう。この後少し変更を入れますが、そのあたりは追って。

上述を差し込んだ前提で、まずはログインです。
ログインでやりたい事は
・IDとパスワードが一致していることを条件に
・・「現在認証中」であることの目印を持つ事
が最低限必要になります。

前回の authentication_id_pass のis_authenticationメソッドにざっくりと肉付けをしてみましょう。
また、ユーザ情報はDBに入っていて、パスワードは「ソルト付きのsha-1」で格納されている、と仮定します。

list 2

authentication_id_pass より

  1    public function is_authentication()
  2    {
  3      
// ユーザが入力したIDと合致する「DBないユーザ情報」を取得
  4      // XXX 戻り値はハッシュ配列である、とする
  5      
$user_datas DBからユーザ情報を取得する($this->get_id());
  6  
  7      
// もしIDが存在しなければfalse
  8      
if (true === empty($user_datas)) {
  9        return 
false;
 10      }
 11  
 12      
// 入力されたパスワードを「ソルト付きハッシュ文字列」にする
 13      
$pass sha1コンフィグ情報->探す('password_seed') . $this->get_pass() );
 14  
 15      
// 比較する
 16      
if ($pass === $user_datas['pass']) {
 17        return 
true;
 18      }
 19      
// パスワードが違ったらしい
 20      
return false;
 21    }

次に、上述を呼び出すところを作ってみましょう。
先に実装をお見せしてから、実装に対する説明をします。

list 3
  1    //
  2    
$auth_obj = new authentication_id_pass();
  3  
  4    
//
  5    
$auth_obj->set_id$cgi_request->find('id') );
  6    
$auth_obj->set_pass$cgi_request->find('pass') );
  7  
  8    
//
  9    
$r $auth_obj->is_authentication();
 10    if (
false === $r) {
 11      
// ログイン失敗処理
 12      
return ;
 13    }
 14    
// else
 15    // ログイン成功処理
 16    // セッションIDを新しいモノに差し替えて
 17    
session_regenerate_id(true);
 18    
// セッション変数にIDを設定して
 19    
$_SESSION['user_id'] = $auth_obj->get_id();
 20    
// セッションの寿命を計算するための基準軸を設定
 21    
$_SESSION['session_time'] = time();
 22  
 23    
// XXX 以下、処理継続

がる先生コアになるのは「 $_SESSION['user_id'] にユーザIDが入っていたら、認証されているセッションとみなす」という部分になります。
念のため、authenticationに成功した時点で、その前までに、anonymous authとして使っていたセッションIDを破棄しています。

また、同一のセッションIDをあまり長々と使っているとセッションハイジャックなどにあいやすいのですが、かといって「1アクセス毎に」セッションIDを変えるのも、少々サーバに負担がかかります。
というわけで、セッションIDを「一定時間ごとに」変更するような設定をしています。 ただこのままだと設定だけなので、list 1に、この「セッションIDの変更」を組み込みます。

  • 1
  • 2


Pick Up Q&A

Q
負荷時のmysql_connect()エラー
 このエントリーをはてなブックマークに追加 
A
これはPHPというよりOSまたはMySQLのコミュニティで質問されたほうがいいと思います。 ぱっと思いついた範囲で記すと MySQL等のDBに「ある時点において同時に接続可能なクライアントの最大数」に制限があるよう...

>>続きを読む

今回のような実践的な経験がエンジニアのキャリアに繋がると思います。是非サービスを成功させて下さい!

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)