yii IUserIdentity验证类的使用

验证和授权在页面需要限制访问时用到。验证就是确认某人就是他所声称的那个人。通常涉及到用户名和密码,但也包含其他方式,例如智能卡,指纹等。授权是在验证用户后,查明他是否被允许管理指定的资源。通常判断他是否是有权访问资源的角色的成员。

Yii 有一个内置的验证/授权框架,它易于使用且可定制。

Yii 认证框架的核心是预声明的用户组件,它是一个实现 IWebUser 接口的对象。用户组件代表了当前用户的持久身份信息。可以使用 Yii::app()->user 来访问。

使用用户组件,可以使用 CWebUser::isGuest 检查一个用户是否已经登录;我们可以登录或者注销一个用户; 调用 CWebUser::checkAccess 可以检查用户是否可以执行特定的操作; 也可以得到用户的唯一身份和另外的持久身份信息。

定义身份类

如之前所说, 验证是确认用户的身份。典型的网络应用验证通常是使用用户名和密码的组合来确认用户的身份。然而,也可以包含其他的方法。为了掩饰兼容各种验证方法, Yii 认证框架引入了身份类。

我们定义一个身份类,它含有实际的验证逻辑。身份类应当实现 IUserIdentity 接口。不同的身份类可以实现不同的验证方法 (例如 OpenID, LDAP, Twitter OAuth, Facebook Connect). 推荐扩展 CUserIdentity 编写你自己的类,CUserIdentity 是使用用户名和密码这种验证方法的基类。

定义身份类最主要的工作是实现 [IUserIdentity::authenticate] 方法. 这个方法封装了验证的逻辑细节。在身份类中也可以声明额外的身份信息。

例子

在下面的例子中,我们使用一个身份类来演示使用数据库方法来验证。这是非常典型的方法。用户需要输入用户名和密码到登录表单中,然后我们验证这些账号信息,使用 ActiveRecord ,向数据库中的表来查询。我们需要演示的是

  • 实现 authenticate() 方法来根据数据库验证账号信息.
  • 重写 CUserIdentity::getId() 方法来返回 _id 属性,因为默认返回用户名作为 ID.
  • 使用 setState() (CBaseUserIdentity::setState) 方法来演示储存其他信息,这些信息可以在随后的访问被轻松获取

<?php

class UserIdentity extends CUserIdentity

{

private $_id;

public function authenticate()

{

$record=User::model()->findByAttributes(array(‘username‘=>$this->username));

if($record===null)

$this->errorCode=self::ERROR_USERNAME_INVALID;

else if($record->password!==md5($this->password))

$this->errorCode=self::ERROR_PASSWORD_INVALID;

else

{

$this->_id=$record->id;

$this->setState(‘title‘, $record->title);

$this->errorCode=self::ERROR_NONE;

}

return !$this->errorCode;

}

public function getId()

{

return $this->_id;

}

}

?>

下个小结的登录和注销中,我们将看到把这个身份类放在用户的登录方法中。任何储存在状态中的信息 (使用 CBaseUserIdentity::setState) 将被传递给 CWebUser, 它们被保存到持久存储中,例如 session. 这些信息可以作为 CWebUser 的属性被访问。在我们的例子汇总,使用 $this->setState(‘title‘,$record->title) 存储用户 title 信息. 在登录完成之后,可以使用 Yii::app()->user->title 得到当前用户的 title 信息。

信息: CWebUser 默认使用 session 作为用户身份信息的持久存储方式。若启用了基于 cookie 的登录 (通过设置 CWebUser::allowAutoLogin 为 true), 用户身份也可以被保存在 cookie 中。一定不要声明敏感信息 (例如密码) 为 persistent.

登录和注销

现在已经看到了创建一个用户身份的例子,我们使用它来简化登录和注销动作。如下代码展示了它们如何被实现的:

<?php

// Login a user with the provided username and password.

$identity=new UserIdentity($username,$password);

if($identity->authenticate())

Yii::app()->user->login($identity);

else

echo $identity->errorMessage;

......

// Logout the current user

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

?>

这里我们创建了一个 UserIdentity 对象并传递账号信息 (也就是用户提交的 $username 和 $password ) 到它的构造器中. 然后我们只需调用 authenticate() 方法. 若成功,传递身份信息到 CWebUser::login 方法,在此方法中身份信息被存储到持久存储 (默认是 PHP session ) . 若验证失败, 我们可以查询 errorMessage 属性来了解为何失败.

判断一个用户是否登录非常简单,使用 Yii::app()->user->isGuest 即可. 若使用持久存储如 session (默认地) 和/或 cookie (下面讨论) 来存储身份信息, 用户在随后的请求中保持已登录状态. 这样,我们无需为每次请求使用 UserIdentity 类和完整的登录验证. CWebUser 将自动从持久存储中载入身份信息,用它们来检测Yii::app()->user->isGuest 返回的是 true 还是 false.

基于 cookie 的登录

默认情况下, 用户在一段闲置期限后将被注销, 取决于 session 配额. 为了改变这个行为, 我们可以设置 user 组件的 allowAutoLogin 属性为 true 并传递 duration 参数到 CWebUser::login 方法中. 在指定的期限内用户仍然处于登录状态,即使他关闭了浏览器窗口 注意此特征需要用户的浏览器接受 cookie.

<?php

// Keep the user logged in for 7 days.

// Make sure allowAutoLogin is set true for the user component.

Yii::app()->user->login($identity,3600*24*7);

?>

如之前所述,当启用了基于 cookie 的登录, 通过 CBaseUserIdentity::setState 存储的状态将也保存在 cookie 中. 下次用户登录时, 这些状态从 cookie 中读取,并且可以使用 Yii::app()->user 来访问。

虽然 Yii 有方法来防止状态 cookie 在客户端被篡改, 我们强烈建议安全敏感信息不要储存为状态. 而是选择存储在服务器端,从服务器端的持久存储中读取 (例如数据库).

此外, 位于要求较高的网络应用,我们建议使用如下策略来增强基于 cookie 登录的安全性:

  • 当用户填写登录表单后成功登录, 在 cookie 状态和服务器端的持久存储(如数据库)中生成并存储一个随机 key .
  • 在随后的访问中, 当通过 cookie 信息实现验证后, 我们对比这两个随机 key 来确保登录前他们是一致的。
  • 若用户通过表单再次登录, key 需要重新生成.

通过使用上面的策略, 我们消除了这种可能性:一个用户可以重新使用旧的包含过期 state 信息的 state cookie。

为了实现上面的策略, 我们需要重写如下两个方法:

  • CUserIdentity::authenticate(): 这里是认证真正执行的地方. 若用户被认证, 我们应当重新生成一个新的随机 key, 并把它存储到数据库以及身份状态中( 通过CBaseUserIdentity::setState).
  • CWebUser::beforeLogin(): 它在用户登录时被调用. 我们应当检查 state cookie 中的 key 是否和数据库中的是相同的

yii IUserIdentity验证类的使用

时间: 2024-11-08 22:26:36

yii IUserIdentity验证类的使用的相关文章

yii自定义验证

自定义验证类 class BaseModel extends Model { public function rules() { return [ ['obj', ContentSecurityValidator::class], ]; } public function exec() { if (!$this->validate()) { return [ 'errors' => $this->errors ]; } } public function attributeLabels(

js 验证表单 js提交验证类

js 验证表单 js提交验证类 附加:js验证radio是否选择 <script language="javascript">function checkform(obj){for(i=0;i<obj.oo.length;i++)         if(obj.oo[i].checked==true) return true; alert("请选择")return false; }</script><form id="f

C# System.Attribute(验证类)

本文以一个项目中通用的验证类来举例说明如何使用自定义Attribute来扩展元数据.  在项目中,我们为了保证各个层次之间的松藕合,通常把在各个层次之间传递数据的封装在一个称为实体类的类中,比如ActionFrom [csharp] view plaincopy using System; namespace AttributeTest { public class ActionForm { private string email = ""; private string passw

JS表单验证类HTML代码实例

以前用的比较多的一个JS表单验证类,对于个人来说已经够用了,有兴趣的可以在此基础上扩展成ajax版本.本表单验证类囊括了密码验证.英文4~10个 字符验证. 中文非空验证.大于10小于100的数字.浮点数验证.日期验证.邮件检查.网址验证.固定电话和手机号码验证.IP地址验证.邮编和QQ号码验证. MSN和身份证验证等. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.

Yii2的深入学习--yii\base\Event 类

根据之前一篇文章,我们知道 Yii2 的事件分两类,一是类级别的事件,二是实例级别的事件.类级别的事件是基于 yii\base\Event 实现,实例级别的事件是基于 yii\base\Component 实现. 今天先来看下类级别事件的实现,代码是 yii\base\Event 类. <?php namespace yii\base; /** * Event is the base class for all event classes. */ class Event extends Obje

一个PHP常用表单验证类(基于正则)

一个基于正则表达式的PHP常用表单验证类,作者:欣然随风.这个表单判断类的功能有:验证是否为指定长度的字母/数字组合.验证是否为指定长度汉字.身 份证号码验证.是否是指定长度的数字.验证邮件地址.电话号码.验证邮编.url地址.数据库转义.数据格式还原等.在平时的PHP项目开发中,这些都比 较常用哦,下面把代码分享给大家: <?php /** * 页面作用:常用表单验证类 * 作 者:欣然随风 * QQ:276624915 */ class class_post { //验证是否为指定长度的字母

字符串验证类

/***************************************************** * 文件名:StringValidation.cs * 功能描述:扩展方法:字符串验证 * 创建时间:2014-6-7 * 作 者: Eric * * 修改时间: * 修改人: * 修改描述 * ******************************************************/ public static class StringValidation { //

Yii 验证码验证

控制器如下 LoginForm如下 视图如下 <div class="loginbody">            <span class="systemlogo"></span>             <div class="loginbox">                <ul>                    <?php $form = $this->beg

php 验证类

<?php /** * 验证类 * * @lastmodify 2014-5-16 * @author jy625 */ class VerifyAction{ /** * 是否为空值 */ public static function isEmpty($str){ $str = trim($str); return !empty($str) ? true : false; } /** * 数字验证 * param:$flag : int是否是整数,float是否是浮点型 */ public s