• Yii创建前台和后台登录表单和通过扩展 CWebUser 增加信息到 Yii::app()->user


     

    我参考了这篇文章来构建项目的前台和后台的目录结构。感谢Andy的这篇文章。按照所有的步骤,您将有单独的前台和后台面板,如:

    • http://localhost/index.php // 前台
    • http://localhost/backend.php // 后台管理

    我使用了两个不同的数据模型来处理前台和后台的用户数据库

    1. 用户 User
    2. 管理用户 AdminUser

    LoginForm 登录表单

    路径: models/LoginForm.php

    在这里,我给这个类添加了新的变量,即 userType(用户类型)

    class LoginForm extends CFormModel
    {
    public $username;
    public $password;
    public $rememberMe;
    public $userType; // 添加的新成员变量
     
    private $_identity;
     
    public function __construct($arg='Front') { // 默认设置为前台   
        $this->userType = $arg;
    }
    //==== 其余代码如下 ====
    public function authenticate($attribute,$params)
    {
        if(!$this->hasErrors())
        {
            $this->_identity=new UserIdentity($this->username,$this->password);
            $this->_identity->userType = $this->userType; // 这将会把标识传递给 UserIdentify
            if(!$this->_identity->authenticate())
            $this->addError('password','Incorrect username or password.');
        }
    }

    UserIdentity:

    路径: components/UserIdentity.php

    向 LoginForm 一样,添加新的成员变量

    <?php
    class UserIdentity extends CUserIdentity
    { 
        public $userType = 'Front';
     
        public function authenticate()
        {
            if($this->userType=='Front') // 只是前台登录
            {
                // 检查登录信息是否存在于数据库中
                $record=User::model()->findByAttributes(array('username'=>$this->username));
                if($record===null)
                { 
                    $this->errorCode=self::ERROR_USERNAME_INVALID;
                }else if($record->password!==$this->password)            // 在这里比较数据中的密码与登录信息中的密码
                {
                    $this->errorCode=self::ERROR_PASSWORD_INVALID;
                }else{  
                    $this->setState('userId',$record->userId);
                    $this->setState('name', $record->firstName.' '.$record->lastName);
                    $this->errorCode=self::ERROR_NONE;
                }
                return !$this->errorCode;
            }
            if($this->userType=='Back')// 这里是后台管理登录
            {
                // 检查登录信息是否存在于数据库中
                $record=AdminUser::model()->findByAttributes(array('email'=>$this->username));  // 这里我用数据库中的邮箱作为用户名
                if($record===null)
                { 
                    $this->errorCode=self::ERROR_USERNAME_INVALID;
                }else if($record->password!==base64_encode($this->password)) // 获取base64_encode加密的密码并于数据库中的密码比较
                { 
                    $this->errorCode=self::ERROR_PASSWORD_INVALID;
                }else
                {  
                    $this->setState('isAdmin',1);
                    $this->setState('userId',$record->userId);
                    $this->setState('name', $record->name);
                    $this->errorCode=self::ERROR_NONE;
                }
                    return !$this->errorCode;
            }
        }
    }

    Code in action: 

    Now all is set, we just need to use LoginForm object in controller files.

    Path: Controllers/Front/SiteController.php

    $model=new LoginForm('Front'); // Front side login form which will use 'User' module

    Path: Controllers/Back/SiteController.php

    $model=new LoginForm('Back'); // Admin side login form which will use 'AdminUser' module

    You may also find some good articles on how to manage user access levels..etc. But as a beginner i tried this code, It may help you. Share your thoughts and comments.

    默认的用gii创建的actionLogin()方法:

            $model=new LoginForm;
    
            // if it is ajax validation request
            if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
            {
                echo CActiveForm::validate($model);
                Yii::app()->end();
            }
    
            // collect user input data
            if(isset($_POST['LoginForm']))
            {
                $model->attributes=$_POST['LoginForm'];
                // validate user input and redirect to the previous page if valid
                if($model->validate() && $model->login())
                    $this->redirect(Yii::app()->user->returnUrl);
            }
            // display the login form
            $this->render('login',array('model'=>$model));

    参考:http://www.yiiwiki.com/27/

    UserIdentity是Yii管理用户登录状态的类,它提供了保存除登录状态和ID之外的其它信息的能力,比如我们想要保存整个User Model(通常不必要,但是这里只是举个例子),可以通过将一个User Model的实例放在UserIdentity的State集合中来实现:

    复制代码
        public function authenticate()
        {
            $userService=new UserService;
            $userRecord = $userService->login($this->username,$this->password);
            if($userRecord==NULL)
                $this->errorCode=self::ERROR_PASSWORD_INVALID;
            else
            {
                $this->errorCode=self::ERROR_NONE;
                $this->_id=$userRecord->user_id;
                
                $this->setState('userRecord',$userRecord);//将User Model的实例放到States集合中
            }            
                
            return !$this->errorCode;
        }
    复制代码

     有一个地方值得注意一下,即通过setState()方法将用户的role储存在session中,完成这个操作后,我们可以通过Yii::app()->user->role来获取用户的role。当然,也可以为ID做相同的处理,但是内嵌的验证已经包含了getId()方法,回用户的标识符,默认返回username。可以通过override重写方法使其返回ID。(id和name方法CUserIdentity中已经写了,都返回$this->username,我们把id

    重写下。

     最后重写getId():

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

      这样用户的ID就可以通过Yii::app()->user->id获得了。

    最开始我

    ChromePhp::log(Yii::app()->user->id); 
    ChromePhp::log(Yii::app()->user->name);
    ChromePhp::log(Yii::app()->user->isGuest);

    总是返回null,Guest,true是因为没有login

    $duration=$this->rememberMe?3600:0;
    Yii::app()->user->login($this->_identity,$duration);

    登陆后就会输出相应id,用户名和是否是guest了。

      先在UserIdentity中创建私有变量$_id:

    class UserIdentity extends CUserIdentity
    {
        // Need to store the user's ID:
        private $_id;

      验证成功(else语句)时将用户ID复制给该变量:

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

    当我们需要User的用户名的时候,可以从UserIdentity的State中取出User Model的实例(例子中的$userRecord)然后再取出用户名:

      //userRecord保存的是一个Model的User对象
        $userName = Yii::app()->user->userRecord->user_name;

    保存在UserIdentity中的$userRecord实例什么时候被销毁呢?如果用户不退出它是一值可以访问的,这个可能一般不会怀疑。那如果用户退出呢,我们是否需要手动从UserIdentity中移除$userRecord? 就像这样:

     public function actionLogout()
        {
            Yii::app()->user->logout();
            unset(Yii::app()->user->userRecord);
            $this->redirect('login');
        }

    事实上不需要,'unset'这一行代码什么都没做,因为userRecord在调用unset的时候已经不存在了。要验证这一点很简单,将'unset'这一行代码换成访问userRecord的代码,比如这样:

    $userName = Yii::app()->user->userRecord->user_name

    你会发现Yii报错了——“userRecord未定义",说明userRecord在调用UserIdentity的logout之后已经被销毁了,为什么呢?这个跟UserIdentity的State集合的实现有关:State集合实际上是一个http session的简单包装,放到State集合的东西实际上是放在session里的。源代码很清楚的说明了这一点:

    复制代码
        public function setState($key,$value,$defaultValue=null)
        {
            $key=$this->getStateKeyPrefix().$key;
            if($value===$defaultValue)
                unset($_SESSION[$key]);
            else
                $_SESSION[$key]=$value;
        }
    复制代码

    当调用UserIdentity的logout时,或者销毁整个session或者调用clearStates方法。clearStates就是unset session中相应的变量,看看源代码:

    复制代码
        public function clearStates()
        {
            $keys=array_keys($_SESSION);
            $prefix=$this->getStateKeyPrefix();
            $n=strlen($prefix);
            foreach($keys as $key)
            {
                if(!strncmp($key,$prefix,$n))
                    unset($_SESSION[$key]);
            }
        }
    复制代码

    所以,退出的时候直接简单的调用UserIdentity的logout就行了,不需要再手动清理存放在State集合中的信息

    转自:http://www.cnblogs.com/yiimaster/archive/2012/04/12/2444999.html

    参考:http://www.cnblogs.com/hi-bazinga/archive/2012/05/17/2506368.html

    Yii->user(当前用户)相关

    常用的用法是 

    Php代码  收藏代码
    1. class Controller extends CController  
    2. {  
    3.     public $user = null;  
    4.     $this->user = Yii:app()->user;  
    5. }  


    this->user->isGuest; 
    this->user->id; 
    this->user->name; 

    还有设置session 
    this->user->setStatus('xx'); 
    this->user->getStatus('xx'); 

    查看一下手册后,发现user的属性和方法还真多。 

    详细如下: 
    CWebUser represents the persistent state for a Web application user. 

    CWebUser is used as an application component whose ID is 'user'. Therefore, at any place one can access the user state via 

    Yii::app()->user. 

    CWebUser should be used together with an identity which implements the actual authentication algorithm. 

    A typical authentication process using CWebUser is as follows: 
    1.The user provides information needed for authentication. 
    2.An identity instance is created with the user-provided information. 
    3.Call IUserIdentity::authenticate to check if the identity is valid. 
    4.If valid, call CWebUser::login to login the user, and Redirect the user browser to returnUrl. 
    5.If not valid, retrieve the error code or message from the identity instance and display it. 


    The property id and name are both identifiers for the user. The former is mainly used internally (e.g. primary key), while the 

    latter is for display purpose (e.g. username). The id property is a unique identifier for a user that is persistent during the 

    whole user session. It can be a username, or something else, depending on the implementation of the identity class. 

    Both id and name are persistent during the user session. Besides, an identity may have additional persistent data which can be 

    accessed by calling getState. Note, when cookie-based authentication is enabled, all these persistent data will be stored in 

    cookie. Therefore, do not store password or other sensitive data in the persistent storage. Instead, you should store them 

    directly in session on the server side if needed. 


    1,属性 
    allowAutoLogin      boolean        whether to enable cookie-based login. CWebUser 
    authTimeout         integer        timeout in seconds after which user is logged out if inactive. CWebUser 
    autoRenewCookie     boolean        whether to automatically renew the identity cookie each time a page is requested. CWebUser 
    autoUpdateFlash     boolean        whether to automatically update the validity of flash messages. CWebUser 
    behaviors           array          the behaviors that should be attached to this component. CApplicationComponent 
    flashes             array          Returns all flash messages. CWebUser 
    guestName           string         the name for a guest user. CWebUser 
    id                  mixed          the unique identifier for the user. CWebUser 
    identityCookie      array          the property values (in name-value pairs) used to initialize the identity cookie. CWebUser 
    isGuest             boolean        whether the current application user is a guest. CWebUser 
    isInitialized       boolean        Checks if this application component bas been initialized. CApplicationComponent 
    loginUrl            string|array   the URL for login. CWebUser 
    name                string         Returns the unique identifier for the user (e.g. username). CWebUser 
    returnUrl           string         Returns the URL that the user should be redirected to after successful login. CWebUser 
    stateKeyPrefix      string         a prefix for the name of the session variables storing user session data. CWebUser 



    2,方法 
    最基本的方法 
    除了call, get, isset, set, unset方法之外,还有 
    getIsInitialized() Checks if this application component bas been initialized. //一般不需要检查 
    checkAccess() Performs access check for this user.   //检查用户可以访问的操作 
    方法原型:public boolean checkAccess(string $operation, array $params=array ( ), boolean $allowCaching=true) 


    基本方法 
    getId() Returns the unique identifier for the user. If null, it means the user is a guest. 
    setId() Sets the unique identifier for the user. If null, it means the user is a guest. 
    getName() Returns the unique identifier for the user (e.g. username). 
    setName() Sets the unique identifier for the user (e.g. username). 
    setReturnUrl() Sets the URL that the user should be redirected to after login. 
    getReturnUrl() Returns the URL that the user should be redirected to after successful login. 
    canGetProperty() Determines whether a property can be read. 
    canSetProperty() Determines whether a property can be set. 


    登陆相关 
    login() Logs in a user. CWebUser 
    loginRequired() Redirects the user browser to the login page.//该方法非常好用 
    logout() 
    getIsGuest() 


    增加行为相关 
    attachBehavior() Attaches a behavior to this component. CComponent 
    attachBehaviors() Attaches a list of behaviors to the component. 
    detachBehavior() Detaches a behavior from the component. CComponent 
    detachBehaviors() Detaches all behaviors from the component. CComponent 
    disableBehavior() Disables an attached behavior. CComponent 
    disableBehaviors() Disables all behaviors attached to this component. CComponent 
    enableBehavior() Enables an attached behavior. CComponent 
    enableBehaviors() Enables all behaviors attached to this component. 


    session相关 
    setState() Stores a variable in user session. // 是基于cookie-based authentication,所以不应存一些如密码等敏感信息 
    getState() Returns the value of a variable that is stored in user session. 
    hasState() Returns a value indicating whether there is a state of the specified name. 
    clearStates() Clears all user identity information from persistent storage. 
    setStateKeyPrefix() Sets a prefix for the name of the session variables storing user session data. 
    getStateKeyPrefix() Returns a prefix for the name of the session variables storing user session data. 


    flash相关 
    hasFlash() Determines whether the specified flash message exists 
    getFlash() Returns a flash message. 
    setFlash() Stores a flash message. 
    getFlashes() Returns all flash messages. 


    事件相关 
    raiseEvent() Raises an event. 
    hasEvent() Determines whether an event is defined. 
    hasEventHandler() Checks whether the named event has attached handlers. 
    getEventHandlers() Returns the list of attached event handlers for an event. 
    attachEventHandler() Attaches an event handler to an event. 
    detachEventHandler() Detaches an existing event handler. 

    --------------------------

    通过扩展 CWebUser 增加信息到 Yii::app()->user

    通过扩展 CWebUser 增加信息到 Yii::app()->user 

    此教程解释了:如何通过增加一个扩展自 CWebUser 并从名为 User 的数据表中检索用户信息的组件,从 Yii::app()->user 检索更多参数。 

    也有另外一个方法来完成这个任务,它从 session 或 cookie 中检索变量: 
    How to add more information to Yii::app()->user (based on session or cookie)。 

    步骤如下: 
    1. 确保你已经有一个数据库 User 模型。 
    2. 创建一个扩展自 CWebUser 的组件。 
    3. 在 config.php 中指定应用使用的用户类。 

    1. User 模型应当如下: 
    <?php 

    // this file must be stored in: 
    // protected/models/User.php 

    class User extends CActiveRecord 

         
        public static function model($className=__CLASS__) 
        { 
            return parent::model($className); 
        } 

         
        public function tableName() 
        { 
            return 'User'; 
        } 

    ?> 

    2. 然后我们创建 WebUser 组件: 
    <?php 

    // this file must be stored in: 
    // protected/components/WebUser.php 

    class WebUser extends CWebUser { 

      // Store model to not repeat query. 
      private $_model; 

      // Return first name. 
      // access it by Yii::app()->user->first_name 
      function getFirst_Name(){ 
        $user = $this->loadUser(Yii::app()->user->id); 
        return $user->first_name; 
      } 

      // This is a function that checks the field 'role' 
      // in the User model to be equal to 1, that means it's admin 
      // access it by Yii::app()->user->isAdmin() 
      function isAdmin(){ 
        $user = $this->loadUser(Yii::app()->user->id); 
        return intval($user->role) == 1; 
      } 

      // Load user model. 
      protected function loadUser($id=null) 
        { 
            if($this->_model===null) 
            { 
                if($id!==null) 
                    $this->_model=User::model()->findByPk($id); 
            } 
            return $this->_model; 
        } 

    ?> 

    3. 最后一步,配置应用 
    <?php 
    // you must edit protected/config/config.php 
    // and find the application components part 
    // you should have other components defined there 
    // just add the user component or if you 
    // already have it only add 'class' => 'WebUser', 

    // application components 
    'components'=>array( 
        'user'=>array( 
            'class' => 'WebUser', 
            ), 
    ), 
    ?> 

    现在你可以使用如下命令: 
    Yii::app()->user->first_name - 返回名字的属性 
    Yii::app()->user->isAdmin() - 返回 admin 状态的函数 
    现在你可以增加你想要的任何函数到 WebUser 组件。

    转自:http://blog.sina.com.cn/s/blog_4291fcdb0100tavh.html

    http://www.yiiframework.com/wiki/60/

    更多:http://hudeyong926.iteye.com/blog/1338494

  • 相关阅读:
    java中的异常类
    Mysql--JDBC的基础
    eclipse使用断言
    idea中使用断言
    java的null
    array,集合(collection),集合(list)的区别
    命名管道FIFO
    标准库中的管道操作
    现代进程间的通信方式--管道
    广播编程之发送者
  • 原文地址:https://www.cnblogs.com/youxin/p/3580994.html
Copyright © 2020-2023  润新知