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

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 是否和数据库中的是相同的

在下面的例子中,我们使用一个身份类来演示使用数据库方法来验证。这是非常典型的方法。用户需要输入用户名和密码到登录表单中,然后我们验证这些账号信息,使用 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;
    }
}
?>

Yii入门,登录的更多相关文章

  1. yii自动登录

    在yii,登录页面选择记住密码,下次就会自动登陆 前些天,自己增加了一个web应用,但是发现虽然选择记住密码,没选退出,关闭浏览器,重新进入还会跳转到登陆页面 自动登录是利用cookie实现的 配置U ...

  2. yii中登录后跳转回登录前请求的页面

    当我们请求一个经过权限控制的请求不通过时,会跳转到一个地方请求权限,请求结束后需要跳转回之前的页面.比如我们请求一个需要登录的action,会被跳转到login页面,我们希望登录成功后跳转到我们之前希 ...

  3. 【YII】Yii入门

    1. 入门博客 http://blog.csdn.net/zm2714/article/category/1359776/2 2. 创建运行demo http://blog.csdn.net/zhou ...

  4. yii 用户登录验证(cwebuser) yii 用户登录 (记)

    yii 的确是一个强大而臃肿的框架,简单的小项目,或者只做后台接口调用的项目,建议不要用. 今天记录一下yii使用中cwebuser(Yii::app()->user->login())登 ...

  5. Yii入门☞应用

    Yii 应用的静态结构 应用: require可以有返回值,Yii中经常返回数组用以配置.以前只知道引用文件成功返回1. controllerMap属性允许你指定一个控制器ID到任意控制器类,修改配置 ...

  6. Yii入门教程

    1准备Yii源码 首先新建helloyii目录作为Web应用的根目录,并添加到Nginx的配置文件中.然后将Yii框架源码部署到helloyii下,目录结构如下: helloyii/ |-- fram ...

  7. php爬虫入门 - 登录抓取内容

    PHP 写爬虫 说实话我也想用Python的,毕竟人家招牌.无奈我Python还停留在看语法的阶段,实在太惭愧,鞭笞一下自己加油学习.这里用php的CURL库进行页面抓取. 同事使用的系统需要先登录, ...

  8. Yii 用户登录验证

    http://blog.sina.com.cn/s/blog_685213e70101mo4i.html 1)首先在model文件夹中新建文件 LoginForm.php 代码如下 <?php ...

  9. Yii 入门

    跳转到不同module Redirect to module after login Yii $this->redirect( array('/tradesman/default/index') ...

随机推荐

  1. PageLayoutControl的基本操作

    整理了下对PageLayoutControl的基本功能操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 ...

  2. http://www.360doc.com/content/12/1014/00/7471983_241330790.shtml

    http://www.360doc.com/content/12/1014/00/7471983_241330790.shtml

  3. MyBatis学习总结_12_Mybatis+Mysql分页查询

    package cn.tsjinrong.fastfile.util; /** * @ClassName: Page * @Description: TODO(分页组件的父类,用来封装分页的 通用内容 ...

  4. Hadoop namenode无法启动问题解决

    原因:在root账户(非hadoop账户)下操作hadoop会导致很大的问题 首先运行bin/start-all.sh发现namenode没有启动 只有它们 9428 DataNode 9712 Jo ...

  5. opencv 人脸识别 (二)训练和识别

    上一篇中我们对训练数据做了一些预处理,检测出人脸并保存在\pic\color\x文件夹下(x=1,2,3,...类别号),本文做训练和识别.为了识别,首先将人脸训练数据 转为灰度.对齐.归一化,再放入 ...

  6. USACO Section 2.2: Runaround Numbers

    简单题 /* ID: yingzho1 LANG: C++ TASK: runround */ #include <iostream> #include <fstream> # ...

  7. Diving Into Lync Client Logins

    Now that we have a fully functional UC lab it's time to start using the lab to explore various aspec ...

  8. [HIHO1322]树结构判定(并查集)

    题目链接:http://hihocoder.com/problemset/problem/1322 给一个图,判断这个图是不是一棵树. 判定的方法:首先是连通图,其次所有点的入度都小于等于1. /* ...

  9. [CF660C]Hard Process(尺取法)

    题目链接:http://codeforces.com/problemset/problem/660/C 尺取法,每次遇到0的时候补一个1,直到补完或者越界为止.之后每次从左向右回收一个0点.记录路径用 ...

  10. 极限编程,最强N皇后JAVA解题代码,4秒出15皇后,33秒出16皇后

    私人博客原文链接来自:http://www.hexcode.cn/article/show/eight-queen 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化 8皇后以 ...