认证

    Yii提供了一个认证框架,它连接了不同的组件以支持登录。欲使用这个框架,
    你主要需要做以下工作:

    • 设置用户组件 [[yii\web\User|user]] ;
    • 创建一个类实现 [[yii\web\IdentityInterface]] 接口。

    用户组件 [[yii\web\User|user]] 用来管理用户的认证状态。这需要你
    指定一个含有实际认证逻辑的认证类 [[yii\web\User::identityClass|identity class]]。
    在以下web应用的配置项中,将用户用户组件 [[yii\web\User|user]] 的
    认证类 [[yii\web\User::identityClass|identity class]] 配置成
    模型类 , 它的实现将在下一节中讲述。

    认证类 [[yii\web\User::identityClass|identity class]] 必须实现包含以下方法的
    认证接口 [[yii\web\IdentityInterface]]:

    • [[yii\web\IdentityInterface::findIdentity()|findIdentity()]]:根据指定的用户ID查找
      认证模型类的实例,当你需要使用session来维持登录状态的时候会用到这个方法。
    • [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]:根据指定的存取令牌查找
      认证模型类的实例,该方法用于
      通过单个加密令牌认证用户的时候(比如无状态的RESTful应用)。
    • [[yii\web\IdentityInterface::getId()|getId()]]:获取该认证实例表示的用户的ID。
    • [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]:获取基于 cookie 登录时使用的认证密钥。
      认证密钥储存在 cookie 里并且将来会与服务端的版本进行比较以确保
      cookie的有效性。
    • [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]] :是基于 cookie 登录密钥的
      验证的逻辑的实现。

    用不到的方法可以空着,例如,你的项目只是一个
    无状态的 RESTful 应用,只需实现 [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]
    和 [[yii\web\IdentityInterface::getId()|getId()]] ,其他的方法的函数体留空即可。

    1. <?php
    2. use yii\db\ActiveRecord;
    3. use yii\web\IdentityInterface;
    4. class User extends ActiveRecord implements IdentityInterface
    5. {
    6. public static function tableName()
    7. {
    8. return 'user';
    9. }
    10. /**
    11. * 根据给到的ID查询身份。
    12. *
    13. * @param string|integer $id 被查询的ID
    14. */
    15. public static function findIdentity($id)
    16. {
    17. return static::findOne($id);
    18. }
    19. /**
    20. *
    21. * @param string $token 被查询的 token
    22. * @return IdentityInterface|null 通过 token 得到的身份对象
    23. */
    24. public static function findIdentityByAccessToken($token, $type = null)
    25. {
    26. return static::findOne(['access_token' => $token]);
    27. }
    28. /**
    29. * @return int|string 当前用户ID
    30. */
    31. public function getId()
    32. {
    33. return $this->id;
    34. }
    35. /**
    36. * @return string 当前用户的(cookie)认证密钥
    37. public function getAuthKey()
    38. {
    39. return $this->auth_key;
    40. }
    41. * @param string $authKey
    42. * @return boolean if auth key is valid for current user
    43. */
    44. public function validateAuthKey($authKey)
    45. {
    46. return $this->getAuthKey() === $authKey;
    47. }
    48. }

    如上所述,如果你的应用利用 cookie 登录,
    你只需要实现 getAuthKey()validateAuthKey() 方法。这样的话,你可以使用下面的代码在
    user 表中生成和存储每个用户的认证密钥。

    user 应用组件方面,你主要用到 [[yii\web\User]] 。

    你可以使用表达式 Yii::$app->user->identity 检测当前用户身份。它返回
    一个表示当前登录用户的认证类 [[yii\web\User::identityClass|identity class]] 的实例,
    未认证用户(游客)则返回 null。下面的代码展示了如何从 [[yii\web\User]]
    获取其他认证相关信息:

    1. // 当前用户的身份实例。未认证用户则为 Null 。
    2. $identity = Yii::$app->user->identity;
    3. // 当前用户的ID。 未认证用户则为 Null 。
    4. $id = Yii::$app->user->id;
    5. // 判断当前用户是否是游客(未认证的)
    6. $isGuest = Yii::$app->user->isGuest;

    [[yii\web\User::login()]] 方法将当前用户的身份登记到 [[yii\web\User]]。如果 session 设置为
    [[yii\web\User::enableSession|enabled]],则使用 session 记录用户身份,用户的
    认证状态将在整个会话中得以维持。如果开启自动登录 [[yii\web\User::enableAutoLogin|enabled]]
    则基于 cookie 登录(如:记住登录状态),它将使用 cookie 保存用户身份,这样
    只要 cookie 有效就可以恢复登录状态。

    为了使用 cookie 登录,你需要在应用配置文件中将 [[yii\web\User::enableAutoLogin]]
    设为 true。你还需要在 [[yii\web\User::login()]] 方法中
    传递有效期(记住登录状态的时长)参数。

    注销用户:

    1. Yii::$app->user->logout();

    请注意,启用 session 时注销用户才有意义。该方法将从内存和 session 中
    同时清理用户认证状态。默认情况下,它还会注销所有的
    用户会话数据。如果你希望保留这些会话数据,可以换成 Yii::$app->user->logout(false)

    • [[yii\web\User::EVENT_BEFORE_LOGIN|EVENT_BEFORE_LOGIN]]:在登录 [[yii\web\User::login()]] 时引发。
      如果事件句柄将事件对象的 [[yii\web\UserEvent::isValid|isValid]] 属性设为 false,
      登录流程将会被取消。
    • [[yii\web\User::EVENT_AFTER_LOGIN|EVENT_AFTER_LOGIN]]:登录成功后引发。
    • [[yii\web\User::EVENT_BEFORE_LOGOUT|EVENT_BEFORE_LOGOUT]]:注销 [[yii\web\User::logout()]] 前引发。
      如果事件句柄将事件对象的 [[yii\web\UserEvent::isValid|isValid]] 属性设为 false,
      注销流程将会被取消。
    • [[yii\web\User::EVENT_AFTER_LOGOUT|EVENT_AFTER_LOGOUT]]:成功注销后引发。

    你可以通过响应这些事件来实现一些类似登录统计、在线人数统计的功能。例如,
    在登录后 [[yii\web\User::EVENT_AFTER_LOGIN|EVENT_AFTER_LOGIN]] 的处理程序,你可以将用户的登录时间和IP记录到
    user 表中。