在 yii 2.0.47 中,读取用户名需在 identity 类中实现 findbyusername() 方法以支持用户名或邮箱登录,并在 loginform 中调用该方法查找用户、验证密码,同时必须完整实现 identityinterface 的四个方法(findidentity、findidentitybyaccesstoken、getid、getauthkey/validateauthkey),并确保数据库包含 username、password_hash、auth_key 等必要字段。

在 Yii 2.0.47 中,身份验证(Authentication)通常由实现 IdentityInterface 的类完成,比如常见的 User 模型。要“读取用户名”,核心是确保该类正确实现了接口中定义的静态方法 findIdentityByAccessToken() 和实例方法 getId()、getAuthKey()、validateAuthKey(),但最关键的是——如何通过用户名(如 username 或 email)查找并验证用户。
1. 实现 findByUsername() 方法(非接口强制,但最常用)
Yii 官方认证流程(如 LoginForm)默认调用的是自定义的 findByUsername() 静态方法来根据用户名查用户。你需要在你的 Identity 类(如 common\models\User)中添加:
- 该方法接收一个字符串参数(用户名),返回
self|false - 内部使用 ActiveRecord 查询,注意区分大小写(如 MySQL 默认不区分,但建议显式处理)
- 推荐同时支持 username 和 email 登录(可选)
示例代码:
public static function findByUsername($username)
{
return static::findOne([
'or',
['username' => $username],
['email' => $username],
]);
}
2. 在 LoginForm 中调用并验证密码
LoginForm 是典型的身份验证入口。它会调用 User::findByUsername() 获取用户对象,再调用 $user->validatePassword($password) 判断密码是否正确。
- 确保你的 Identity 类中有
validatePassword()方法(通常用Yii::$app->security->validatePassword()) - 登录表单提交后,
login()方法内部会执行:查找用户 → 验证密码 → 调用Yii::$app->user->login($user)
关键片段(LoginForm::login() 内):
$user = User::findByUsername($this->username);
if ($user !== null && $user->validatePassword($this->password)) {
return Yii::$app->user->login($user, $this->rememberMe ? 3600*24*30 : 0);
}
3. 确保 IdentityInterface 方法完整实现
即使你已实现 findByUsername(),也必须完整实现 IdentityInterface 的四个方法,否则登录会报错:
-
findIdentity($id):根据主键查用户(用于 session 或 cookie 登录后的身份恢复) -
findIdentityByAccessToken($token, $type = null):用于 token 认证(如 API),若不用可返回null -
getId():返回用户主键(通常是$this->id) -
getAuthKey()和validateAuthKey():用于基于 cookie 的自动登录,需确保数据库有auth_key字段并已生成
例如 getAuthKey() 应返回数据库字段值:return $this->auth_key;
4. 数据库字段与安全注意事项
为支持用户名登录,数据库表(如 user)至少应包含:
-
id(主键) -
username(唯一,用于登录) -
email(可选,也可作为登录凭据) -
password_hash(存储加密后的密码,不要存明文) -
auth_key(32 位随机字符串,用于 cookie 验证) -
password_reset_token(可选)
生成 auth_key 示例(可在 beforeSave() 中):
if ($this->isNewRecord) {
$this->auth_key = Yii::$app->security->generateRandomString();
}











