[Yii2笔记]044用户验证(Authentication) [ 技术分享 ]
说明
学习Yii Framework 2(易2框架)的过程是漫长的,也是充满乐趣的,以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现,提供了较完整的代码,供你参考。不妥之处,请多多指正!
原文网址:
http://www.yiiframework.com/doc-2.0/guide-security-authentication.html
本文主题:用户验证(Authentication)
用户验证(Authentication)用于验证一个用户的身份标识(identity)。通常会使用一个标识符(identifier)和一个密令(secret token)去判定一个客户是否是他声称的那个身份。用户验证是登录操作的基础。 标识符,如:用户名(username)或邮箱地址(email address) 密令,如:密码或口令 Yii2提供了一个用户验证框架,通过这个框架可以很好的支持登录,并将各个组件上串联起来。要使用这个框架,你只需做两项工作: 1、配置user应用组件 yii\web\User 2、创建一个实现yii\web\IdentityInterface接口的类
1、配置yii\web\User(Configuring yii\web\User)
User(用户)应用组件管理着用户的验证状态,需要你定义一个indetity类,此类中包含着实际的验证逻辑。在下面的应用配置中,user的idetity类配置为app\models\User,如何去实现将在下一节中详述。
return [
'componnets'=>[
'user'=>[
'identityClass'=>'app\models\User',
],
],
];
//配置实例: D:\phpwork\b2b\imall\frontend\config\main.php
return [
'id' => 'app-frontend',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'frontend\controllers',
'components' => [
'user' => [
'identityClass' => 'frontend\models\User',
'enableAutoLogin' => true,
'loginUrl' => ['site/login'],
],
......
];
2、实现yii\web\IdentityInterface接口(Implementing yii\web\IdentityInterface)
findIdentity(),根据给定的user ID查找用户身份类的实例,此方法在通过session维护登录状态时使用。 findIdentityByAccessToken(),使用定义的口令来查找用户身份类的实例,此方法在使用单一口令验证用户身份时使用,多数用于RESTful应用中。 getId(),获取当前用户身份实例的ID。 getAuthKey(),获取一个key,用于验证基于cookie的登录。这个key是存储在登录cookie中,并将与服务器端的版本相比较以确定此cookie是有效的。 validateAuthKey(),它用于实现验证基于cookie登录的key的逻辑。
如果无需实际的方法,你可以使用一个空体实现它。例如,如果你的应用是一个单纯的无状态RESTful应用,你只需实现findIdntityByAccessToken()和getId()方法,而其他的方法体为空即可。 在接下来的这个例子中,一个identity类继承自Active Record类,并与user数据表相关联:
<?php
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface{
public static function tableName(){
return 'user';
}
/**
* Finds an identity by the given ID.
*
* @param string|integer $id the ID to be looked for
* @return IdentityInterface|null the identity object that matches the given ID.
*/
public static function findIdentity($id){
return static::findOne($id);
}
/**
* Finds an identity by the given token.
*
* @param string $token the token to be looked for
* @return IdentityInterface|null the identity object that matches the given token.
*/
public static function findIdentityByAccessToken($token, $type = null){
return static::findOne(['access_token' => $token]);
}
/**
* @return int|string current user ID
*/
public function getId(){
return $this->id;
}
/**
* @return string current user auth key
*/
public function getAuthKey(){
return $this->auth_key;
}
/**
* @param string $authKey
* @return boolean if auth key is valid for current user
*/
public function validateAuthKey($authKey){
return $this->getAuthKey() === $authKey;
}
}
如前所述,你只需实现getAuthKey()和validateAuthKey(),如果你的应用使用的是基于cookie的登录,可以使用以下代码去为每一个用户生成一个验证密钥,并将它存储在use表中。
class User extends ActiveRecord implements IdentityInterface
{
......
public function beforeSave($insert){
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->auth_key = \Yii::$app->security->generateRandomString();
}
return true;
}
return false;
}
}
注意:不要困惑于User标识类和yii\web\User,前者是验证逻辑的实现类,它通常继承自一个AR类,并与用户关键信息的永久存储相关;后者是一个应用组件类,负责管理用户的验证状态。
3、使用yii\web\User(Using yii\web\User)
使用yii\web\User的主要方式是使用user应用组件。 你可以使用表达式Yii::$app->user->identity检测当前用户的身份标识,它将返回一个identity类的实例,这个实例代表当前的登录用户,如果当前用户是未验证的,则返回null,也就是访客(guest)。以下代码演示了如何从yii\web\User获取其他验证相关信息:
//获取用户的identity
$identity=Yii::$app->user->identity;
//获取用户的id
$id=Yii::$app->user->id;
//获取用户是否是访客身份
$isGuest=Yii::$app->user->isGuest;
用户登录
//查找$username的用户身份标识,此前应进行密码或口令验证
$identity=User::findOne(['userName'=>$username]);
//以$identity身份登录系统
Yii::$app->user->login($identity);
yii\web\User::login()方法设置当前用户的身份标识identity到yii\web\User中,如果session有效,此方法将会保存identity到session中,这样用户验证状态将在整个会话过程中被维护。如果基于cookie的登录有效,如"remeber me"登录,它将保存identity到cookie中,这样用户验证状态将在cookie有效期内被cookie所覆盖。 要使基于cookie的登录生效,必须在应用配置中设置yii\web\User::$enableAutoLogin 为true。同时你还需要在调用yii\web\User::login()方法时提供一个保存时长的参数。
退出登录
Yii::$app->user->logout();
注意:会员退出登录仅当session有效时有意义。logout()方法将从内存和session中清除用户登录状态,同时它也会清除掉该用户所有的session数据。如果你想保留session数据,可以调用Yii::$app->user->logout(false)即可。
4、验证事件(Authentication Events)
yii\web\User类为login和logout增加了几个事件:
EVENT_BEFORE_LOGIN,在yii\web\User::login()调用之前运行,如果此事件处理器设置事件对象的isValid属性为false,登录操作将被取消。
EVENT_AFTER_LOGIN,在成功登录后运行。
EVENT_BEFORE_LOGOUT,在yii\web\User::logout()调用之前运行,如果此事件处理器设置事件对象的isValid属性为false,退出操作将被取消。
EVENT_AFTER_LOGOUT,在成功退出后运行。
你可以通过这些事件去实现一些特性,如:登录审计,在线用户统计。举例来说:在EVENT_AFTER_LOGIN处理程序中,你可以在user表中记录登录时间和IP地址。
(全文完)
共 0 条回复
阿江
最后登录:2024-03-03
在线时长:186小时21分
- 粉丝94
- 金钱16816
- 威望160
- 积分20276