在tp中,常使用(tp3.2的时候,其他版本实现方式未知)一个 BaseController,在其 initialize 的方法中,判断$_SESSION 是否登录,如果没有则跳转到 LoginController中,那么在Yii2中该如何实现登录呢?

下面以 backend 应用为例。

第一步,配置认证class

https://www.yiichina.com/doc/guide/2.0/security-authentication

  1. // backend/config/main.php
  2. return [
  3. 'components' => [
  4. 'user' => [
  5. // 此类意味着,使用哪个表的记录作为登录会员class
  6. // 比如 后台使用 admin
  7. // 前台就使用 user
  8. // 所以此处配置的是Admin
  9. 'identityClass' => 'common\models\Admin',
  10. ],
  11. ],
  12. ];

第二步,Admin实现接口

https://www.yiichina.com/doc/guide/2.0/security-authentication#implementing-identity

作为一个认证的class,并不是简单的继承 ActiveRecord就可以,还需要实现相关的接口

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

第三步,登录该怎么写

  1. <?php
  2. // 可参考 advanced 版本中的LoginModel
  3. // 接收前台传递的账号密码
  4. // 根据账号查找管理员是否存在
  5. $admin = Admin::findOne([
  6. 'name' => $name;
  7. ]);
  8. // 比对用户密码是否一致
  9. if (!Yii::$app->security->validatePassword($password, $admin->password)){
  10. // 用户名或者密码错误
  11. }
  12. // 登录
  13. // https://www.yiichina.com/doc/guide/2.0/security-authentication#using-user
  14. // 管理员登录
  15. Yii::$app->user->login($admin);
  16. // ------------------------------------------------------------------------//
  17. // 如何获取当前登录的数据呢
  18. // 注意:其中的 Yii::$app->user 并非指的表 user,而是user组件,也就是这个是一个管理中心,
  19. // 其代表的是 认证class的登录实例。
  20. // 当前用户的身份实例。未认证用户则为 Null 。
  21. $identity = Yii::$app->user->identity;
  22. // 当前用户的ID。 未认证用户则为 Null 。
  23. $id = Yii::$app->user->id;
  24. // 判断当前用户是否是游客(未认证的)
  25. $isGuest = Yii::$app->user->isGuest;

第四步,权限如何拦截

https://www.yiichina.com/doc/guide/2.0/security-authorization#access-control-filter

也是写一个BaseController,所有需要的 controller 都继承与此,就可以实现权限拦截了,更多细节请参考文档。

  1. // 允许所有访客(还未经认证的用户)执行 login 和 signup 动作。
  2. // roles 选项包含的问号 ? 是一个特殊的标识,代表”访客用户”。
  3. // 允许已认证用户执行 logout 动作。@是另一个特殊标识, 代表”已认证用户”。
  4. use yii\web\Controller;
  5. use yii\filters\AccessControl;
  6. class BaseController extends Controller
  7. {
  8. public function behaviors()
  9. {
  10. return [
  11. 'access' => [
  12. 'class' => AccessControl::className(),
  13. 'rules' => [
  14. [
  15. 'allow' => true,
  16. 'roles' => ['@'],
  17. ],
  18. ],
  19. ],
  20. ];
  21. }
  22. }