当ブログアプリケーションでは、システムオーナーとゲストユーザーを区別する必要があります。そのため、ユーザー認証機能を実装する必要があります。
スケルトンアプリケーションは、既にユーザー名とパスワードが両方ともdemo
またはadmin
であるかどうかをチェックすることでユーザー認証を提供していることに気付いているかもしれません。このセクションでは、認証がUser
データベーステーブルに対して行われるように、対応するコードを変更します。
IUserIdentityインターフェースを実装するクラスでユーザー認証が行われます。スケルトンアプリケーションでは、この目的のためにUserIdentity
クラスを使用しています。このクラスは、/wwwroot/blog/protected/components/UserIdentity.php
ファイルに格納されています。
ヒント:慣例により、クラスファイルの名前は、対応するクラス名に拡張子
.php
を付けたものにする必要があります。この慣例に従うことで、パスエイリアスを使用してクラスを参照できます。たとえば、UserIdentity
クラスはapplication.components.UserIdentity
エイリアスで参照できます。Yiiの多くのAPIはパスエイリアスを認識でき(例:Yii::createComponent())、パスエイリアスを使用すると、コードに絶対ファイルパスを埋め込む必要がなくなります。後者の存在は、アプリケーションをデプロイする際にしばしば問題を引き起こします。
UserIdentity
クラスを次のように変更します。
class UserIdentity extends CUserIdentity { private $_id; public function authenticate() { $username=strtolower($this->username); $user=User::model()->find('LOWER(username)=?',array($username)); if($user===null) $this->errorCode=self::ERROR_USERNAME_INVALID; else if(!$user->validatePassword($this->password)) $this->errorCode=self::ERROR_PASSWORD_INVALID; else { $this->_id=$user->id; $this->username=$user->username; $this->errorCode=self::ERROR_NONE; } return $this->errorCode==self::ERROR_NONE; } public function getId() { return $this->_id; } }
authenticate()
メソッドでは、User
クラスを使用して、username
列が与えられたユーザー名と同じ(大文字と小文字を区別しない)tbl_user
テーブルの行を探します。User
クラスは、前のセクションでgii
ツールを使用して作成されたことを思い出してください。User
クラスはCActiveRecordを継承しているため、ActiveRecord機能を利用して、OOP形式でtbl_user
テーブルにアクセスできます。
ユーザーが有効なパスワードを入力したかどうかを確認するために、User
クラスのvalidatePassword
メソッドを呼び出します。/wwwroot/blog/protected/models/User.php
ファイルを次のように変更する必要があります。データベースにプレーンテキストのパスワードを保存する代わりに、パスワードのハッシュを保存することに注意してください。ユーザーが入力したパスワードを検証する際には、代わりにハッシュ結果を比較する必要があります。Yii組み込みのCPasswordHelperを使用して、パスワードをハッシュし、検証します。
class User extends CActiveRecord
{
......
public function validatePassword($password)
{
return CPasswordHelper::verifyPassword($password,$this->password);
}
public function hashPassword($password)
{
return CPasswordHelper::hashPassword($password);
}
}
UserIdentity
クラスでは、tbl_user
テーブルで見つかったユーザーのid
値を返すgetId()
メソッドもオーバーライドしています。親の実装では、代わりにユーザー名が返されます。username
プロパティとid
プロパティの両方がユーザーセッションに保存され、コード内の任意の場所からYii::app()->user
を介してアクセスできます。
ヒント:
UserIdentity
クラスでは、対応するクラスファイルを明示的にインクルードすることなく、CUserIdentityクラスを参照しています。これは、CUserIdentityがYiiフレームワークによって提供されるコアクラスであるためです。Yiiは、コアクラスが初めて参照されたときに、そのクラスファイルが自動的にインクルードされます。
User
クラスでも同じことを行います。これは、User
クラスファイルが/wwwroot/blog/protected/models
ディレクトリに配置されており、アプリケーション設定にある次の行に従ってPHPのinclude_path
に追加されているためです。return array( ...... 'import'=>array( 'application.models.*', 'application.components.*', ), ...... );
上記の構成は、クラスファイルが
/wwwroot/blog/protected/models
または/wwwroot/blog/protected/components
のいずれかの下に位置するクラスは、クラスが初めて参照されたときに自動的にインクルードされることを示しています。
UserIdentity
クラスは主に、ログインページから収集されたユーザー名とパスワードの入力に基づいてユーザーを認証するために、LoginForm
クラスで使用されます。次のコードフラグメントは、UserIdentity
の使用方法を示しています。
$identity=new UserIdentity($username,$password);
$identity->authenticate();
switch($identity->errorCode)
{
case UserIdentity::ERROR_NONE:
Yii::app()->user->login($identity);
break;
......
}
情報:アイデンティティと
user
アプリケーションコンポーネントについて混乱する人がよくいます。前者は認証を実行する方法を表し、後者は現在のユーザーに関連する情報を表すために使用されます。アプリケーションは1つのuser
コンポーネントしか持つことができませんが、サポートする認証の種類に応じて、1つまたは複数のアイデンティティクラスを持つことができます。認証されると、アイデンティティインスタンスは状態情報をuser
コンポーネントに渡すことができるため、user
を介してグローバルにアクセスできます。
変更されたUserIdentity
クラスをテストするには、http://www.example.com/blog/index.php
というURLにアクセスし、tbl_user
テーブルに保存したユーザー名とパスワードでログインを試すことができます。ブログデモで提供されているデータベースを使用する場合は、ユーザー名demo
とパスワードdemo
でログインできるはずです。このブログシステムはユーザー管理機能を提供していないことに注意してください。その結果、ユーザーはWebインターフェースを介してアカウントを変更したり、新しいアカウントを作成したりすることはできません。ユーザー管理機能は、ブログアプリケーションの今後の機能強化として検討できます。
タイプミスを見つけた場合、またはこのページの改善が必要だと考える場合は?
githubで編集する !
UserモデルにgenerateSaltメソッドがありません
ユーザーメソッドにgenerateSaltメソッドを追加する必要があると思います
/** * Generates a salt that can be used to generate a password hash. * @return string the salt */ protected function generateSalt() { return uniqid('',true); }
コメントするにはサインアップまたはログインしてください。