directory search
阅读前篇 简介 Yii 是什么 从 Yii 1.1 升级 入门 安装 Yii 运行应用 第一次问候 使用Forms 数据库应用 使用 Gii 生成代码 进阶 应用结构 概述 入口脚本 应用(Applications) 应用组件(Application Components) 控制器(Controllers) 模型(Models) 视图(views) 模块(Modules) 过滤器(Filters) 小部件(Widgets) 前端资源(Assets) 扩展(Extensions) 请求处理 运行概述 启动引导(Bootstrapping) 路由和创建URL 请求(Requests) 响应(Responses) Sessions 和 Cookies 错误处理(Handling Errors) 日志(Logging) 关键概念 组件(Component) 属性(Property) 事件(Events) 行为(Behaviors) 配置(Configurations) 别名(Aliases) 类自动加载(Autoloading) 服务定位器(Service Locator) 依赖注入容器(Dependency Injection Container) 配合数据库工作 数据库访问 (Data Access Objects) 查询生成器(Query Builder) 活动记录(Active Record) 数据库迁移(Migrations) Sphinx Redis MongoDB Elasticsearch 接收用户数据 创建表单(Creating Forms) 输入验证(Validating Input) 文件上传(Uploading Files) 收集列表输入(Collecting Tabular Input) 多模型的复合表单(Getting Data for Multiple Models) 显示数据 格式化输出数据(Data Formatting) 分页(Pagination) 排序(Sorting) 数据提供器(Data Providers) 数据小部件(Data Widgets) 客户端脚本使用(Working with Client Scripts) 主题(Theming) 安全 认证(Authentication) 授权(Authorization) 处理密码(Working with Passwords) 客户端认证(Auth Clients) 最佳安全实践(Best Practices) 缓存 概述 数据缓存 片段缓存 页面缓存 HTTP 缓存 RESTfull Web服务 快速入门(Quick Start) 资源(Resources) 控制器(Controllers) 路由(Routing) 格式化响应(Response Formatting) 授权认证(Authentication) 速率限制(Rate Limiting) 版本(Versioning) 错误处理(Error Handling) 开发工具 调试工具栏和调试器 使用Gii生成代码 生成API文档 测试 概述(Overview) 配置测试环境(Testing environment setup) 单元测试(Unit Tests) 功能测试(Function Tests) 验收测试(Acceptance Tests) 测试夹具(Fixtures) 高级专题 高级应用模板 创建自定义应用程序结构 控制台命令 核心验证器(Core Validators) 国际化 收发邮件 性能优化 共享主机环境 模板引擎 集成第三方代码 小部件 Bootstrap 小部件 Jquery UI 助手类 概述 Array 助手(ArrayHelper) Html 助手(Html) Url 助手(Url)
characters

认证

认证

认证是鉴定用户身份的过程。它通常使用一个标识符 (如用户名或电子邮件地址)和一个加密令牌(比如密码或者存取令牌)来 鉴别用户身份。认证是登录功能的基础。

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

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

配置 yii\web\User

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

return [
    'components' => [
        'user' => [
            'identityClass' => 'app\models\User',
        ],
    ],
];

认证接口 yii\web\IdentityInterface 的实现

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

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

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

下面的例子是一个通过结合了 user 数据表的 AR 模型 Active Record 实现的一个认证类 yii\web\User::identityClass。

<?php

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface{
    public static function tableName()
    {
        return 'user';
    }

    
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    
    public function getId()
    {
        return $this->id;
    }

    
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }
}

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

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模型 Active Record 实现。后者是负责管理用户认证状态的 应用组件。

使用用户组件 yii\web\User

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

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

// 当前用户的身份实例。未认证用户则为 Null 。$identity = Yii::$app->user->identity;

// 当前用户的ID。 未认证用户则为 Null 。$id = Yii::$app->user->id;

// 判断当前用户是否是游客(未认证的)$isGuest = Yii::$app->user->isGuest;

你可以使用下面的代码登录用户:

// 使用指定用户名获取用户身份实例。// 请注意,如果需要的话您可能要检验密码$identity = User::findOne(['username' => $username]);

// 登录用户
Yii::$app->user->login($identity);

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

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

注销用户:

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

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

认证事件

yii\web\User 类在登录和注销流程引发一些事件。

  • yii\web\User::EVENT_BEFORE_LOGIN:在登录 yii\web\User::login() 时引发。 如果事件句柄将事件对象的 yii\web\UserEvent::isValid 属性设为 false, 登录流程将会被取消。
  • yii\web\User::EVENT_AFTER_LOGIN:登录成功后引发。
  • yii\web\User::EVENT_BEFORE_LOGOUT:注销 yii\web\User::logout() 前引发。 如果事件句柄将事件对象的 yii\web\UserEvent::isValid 属性设为 false, 注销流程将会被取消。
  • yii\web\User::EVENT_AFTER_LOGOUT:成功注销后引发。
你可以通过响应这些事件来实现一些类似登录统计、在线人数统计的功能。例如, 在登录后 yii\web\User::EVENT_AFTER_LOGIN 的处理程序,你可以将用户的登录时间和IP记录到 user 表中。
Previous article: Next article: