Yii框架应用程序整合Ucenter实现同步注册、登录和退出等

本文详细介绍了如何将Discuz论坛程序与Yii应用整合,实现用户单点登录、注册与退出功能。通过创建Ucenter架构并利用Ucenter与Yii应用之间的API接口,实现了用户数据在不同应用间的同步。包括用户信息验证、同步登录、注册、退出等关键功能的实现过程。同时,还展示了如何在Discuz中添加Yii应用的设置,确保无缝集成。
如今很多网站都要整合论坛程序,而康盛的Discuz系列产品往往是首选。然后就有了整合用户的需要,康盛提供了Ucenter架构,方便对不同的应用程序进行单点登录整合。

    进来我尝试将ucenter整合到Yii网站中,获得了成功,虽然登录同步程序不是很妥当,基本使用没有问题了。我将继续改进。下面说说步骤:

  1. 下载安装ucenter和discuz,我使用的是ucenter1.6和discuz7.2,由于7.2自带的uc_client是旧版本,所以需要覆盖一下1.6版本。
  2. 复制一份uc_client文件夹到 protected/vendors/下,然后建立一个ucenter.php文件,内容如下:
    Php代码 复制代码 收藏代码
    1. <?php 
    2. include dirname(__FILE__).'/../config/main.php'
    3. include dirname(__FILE__).'/uc_client/client.php'
    <?php
    include dirname(__FILE__).'/../config/main.php';
    include dirname(__FILE__).'/uc_client/client.php';
    
    可以看到这里只是包含了两个文件。然后打开yii的主配置文件 protected/config/main.php,加入ucenter的一些全局变量的设置:
    Php代码 复制代码 收藏代码
    1. <?php 
    2. define('UC_CONNECT', 'mysql');              // 连接 UCenter 的方式: mysql/NULL, 默认为空时为 fscoketopen() 
    3.                                             // mysql 是直接连接的数据库, 为了效率, 建议采用 mysql 
    4. //数据库相关 (mysql 连接时, 并且没有设置 UC_DBLINK 时, 需要配置以下变量) 
    5. define('UC_DBHOST', 'localhost');           // UCenter 数据库主机 
    6. define('UC_DBUSER', 'root');                // UCenter 数据库用户名 
    7. define('UC_DBPW', '');                  // UCenter 数据库密码 
    8. define('UC_DBNAME', '027xfbbs');                // UCenter 数据库名称 
    9. define('UC_DBCHARSET', 'utf8');             // UCenter 数据库字符集 
    10. define('UC_DBTABLEPRE', '027xfbbs.uc_');            // UCenter 数据库表前缀 
    11.  
    12. //通信相关 
    13. define('UC_KEY', 'ebR4GhhpZB7e9Mhb');               // 与 UCenter 的通信密钥, 要与 UCenter 保持一致 
    14. define('UC_API', 'http://027xf.test/ucenter');  // UCenter 的 URL 地址, 在调用头像时依赖此常量 
    15. define('UC_CHARSET', 'utf8');               // UCenter 的字符集 
    16. define('UC_IP', '');                    // UCenter 的 IP, 当 UC_CONNECT 为非 mysql 方式时, 并且当前应用服务器解析域名有问题时, 请设置此值 
    17. define('UC_APPID', 2);                  // 当前应用的 ID 
    18.  
    19. // uncomment the following to define a path alias 
    20. // Yii::setPathOfAlias('local','path/to/local-folder'); 
    21.  
    22. // This is the main Web application configuration. Any writable 
    23. // CWebApplication properties can be configured here. 
    24. return array
    25.     'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..'
    26.  
    27. ..... 
    <?php
    define('UC_CONNECT', 'mysql');				// 连接 UCenter 的方式: mysql/NULL, 默认为空时为 fscoketopen()
    											// mysql 是直接连接的数据库, 为了效率, 建议采用 mysql
    //数据库相关 (mysql 连接时, 并且没有设置 UC_DBLINK 时, 需要配置以下变量)
    define('UC_DBHOST', 'localhost');			// UCenter 数据库主机
    define('UC_DBUSER', 'root');				// UCenter 数据库用户名
    define('UC_DBPW', '');					// UCenter 数据库密码
    define('UC_DBNAME', '027xfbbs');				// UCenter 数据库名称
    define('UC_DBCHARSET', 'utf8');				// UCenter 数据库字符集
    define('UC_DBTABLEPRE', '027xfbbs.uc_');			// UCenter 数据库表前缀
    
    //通信相关
    define('UC_KEY', 'ebR4GhhpZB7e9Mhb');				// 与 UCenter 的通信密钥, 要与 UCenter 保持一致
    define('UC_API', 'http://027xf.test/ucenter');	// UCenter 的 URL 地址, 在调用头像时依赖此常量
    define('UC_CHARSET', 'utf8');				// UCenter 的字符集
    define('UC_IP', '');					// UCenter 的 IP, 当 UC_CONNECT 为非 mysql 方式时, 并且当前应用服务器解析域名有问题时, 请设置此值
    define('UC_APPID', 2);					// 当前应用的 ID
    
    // uncomment the following to define a path alias
    // Yii::setPathOfAlias('local','path/to/local-folder');
    
    // This is the main Web application configuration. Any writable
    // CWebApplication properties can be configured here.
    return array(
    	'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
    
    .....
    请根据你的情况修改上面的数据库名等设置。
  3. 实现同步注册,我采用的是定义了表单RegisterForm来处理用户的注册,下面是一个典型的注册表单及其验证和业务逻辑代码:
    Php代码 复制代码 收藏代码
    1. <?php 
    2.  
    3. /**
    4. * LoginForm class.
    5. * LoginForm is the data structure for keeping
    6. * user login form data. It is used by the 'login' action of 'SiteController'.
    7. */ 
    8. class RegisterForm extends CFormModel 
    9.     public $username
    10.     public $password
    11.     public $repassword
    12.     public $email
    13.     public $verifyCode
    14.  
    15.     /**
    16.      * Declares the validation rules.
    17.      * The rules state that username and password are required,
    18.      * and password needs to be authenticated.
    19.      */ 
    20.     public function rules() 
    21.     { 
    22.         return array
    23.             // username and password are required 
    24.             array('username, password, repassword, email, verifyCode', 'required'), 
    25.             array('username', 'length', 'max'=>20, 'min'=>5), 
    26.             // 用户名唯一性验证 
    27.             //array('username', 'unique','caseSensitive'=>false,'className'=>'user','message'=>'用户名"{value}"已经被注册,请更换'), 
    28.             array('username', 'checkname'), 
    29.             // 密码一致性验证 
    30.             array('repassword', 'compare', 'compareAttribute'=>'password','message'=>'两处输入的密码并不一致'), 
    31.             // 电子邮件验证 
    32.             array('email', 'email'), 
    33.             // 电子邮件唯一性 
    34.             //array('email', 'unique','caseSensitive'=>false,'className'=>'user','message'=>'电子邮件"{value}"已经被注册,请更换'), 
    35.             array('email', 'checkemail'), 
    36.             //array('birthday', 'match', 'pattern'=>'%^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$%', 'allowEmpty'=>true, 'message'=>'生日必须是年-月-日格式'), 
    37.             //array('mobile', 'length', 'max'=>11, 'min'=>11, 'tooLong'=>'手机号码错误','tooShort'=>'手机号码错误'), 
    38.             array('verifyCode', 'captcha', 'allowEmpty'=> false), 
    39.         ); 
    40.     } 
    41.  
    42.     public function checkname($attribute,$params
    43.     { 
    44.         //ucenter 
    45.         Yii::import('application.vendors.*'); 
    46.         include_once 'ucenter.php'
    47.         $flag = uc_user_checkname($this->username); 
    48.          
    49.         switch($flag
    50.         { 
    51.             case -1: 
    52.                 $this->addError('username', '用户名不合法'); 
    53.                 break
    54.             case -2: 
    55.                 $this->addError('username','包含不允许注册的词语'); 
    56.                 break
    57.             case -3: 
    58.                 $this->addError('username','用户名已经存在'); 
    59.                 break
    60.         } 
    61.     } 
    62.      
    63.     public function checkemail($attribute,$params
    64.     { 
    65.         //ucenter 
    66.         Yii::import('application.vendors.*'); 
    67.         include_once 'ucenter.php'
    68.         $flag = uc_user_checkemail($this->email); 
    69.  
    70.         switch($flag
    71.         { 
    72.             case -4: 
    73.                 $this->addError('email', 'Email 格式有误'); 
    74.                 break
    75.             case -5: 
    76.                 $this->addError('email','Email 不允许注册'); 
    77.                 break
    78.             case -6: 
    79.                 $this->addError('email','该 Email 已经被注册'); 
    80.                 break
    81.         } 
    82.     } 
    83.  
    84.     /**
    85.      * Declares attribute labels.
    86.      */ 
    87.     public function attributeLabels() 
    88.     { 
    89.         return array
    90.             'username'=>'设定用户名'
    91.             'password'=>'设定密码'
    92.             'repassword'=>'再次输入密码'
    93.             'email'=>'电子邮件地址'
    94.             'mobile'=>'手机号码'
    95.             'verifyCode'=>'验证码'
    96.         ); 
    97.     } 
    98.  
    99.     /**
    100.      * 注册用户
    101.      * @return boolean whether register is successful
    102.      */ 
    103.     public function register($uid
    104.     { 
    105.         //ucenter 
    106.         Yii::import('application.vendors.*'); 
    107.         include_once 'ucenter.php'
    108.         $uid = uc_user_register($this->username, $this->password, $this->email); 
    109.         if($uid>0) 
    110.         { 
    111.             $model = new user; 
    112.             $model->attributes = $_POST['RegisterForm']; 
    113.             $model->password = md5($_POST['RegisterForm']['password']); 
    114.             $model->id = $uid
    115.              
    116.             return $model->save(); 
    117.         } 
    118.     } 
    <?php
    
    /**
     * LoginForm class.
     * LoginForm is the data structure for keeping
     * user login form data. It is used by the 'login' action of 'SiteController'.
     */
    class RegisterForm extends CFormModel
    {
    	public $username;
    	public $password;
    	public $repassword;
    	public $email;
    	public $verifyCode;
    
    	/**
    	 * Declares the validation rules.
    	 * The rules state that username and password are required,
    	 * and password needs to be authenticated.
    	 */
    	public function rules()
    	{
    		return array(
    			// username and password are required
    			array('username, password, repassword, email, verifyCode', 'required'),
                array('username', 'length', 'max'=>20, 'min'=>5),
    			// 用户名唯一性验证
    			//array('username', 'unique','caseSensitive'=>false,'className'=>'user','message'=>'用户名"{value}"已经被注册,请更换'),
    			array('username', 'checkname'),
    			// 密码一致性验证
    			array('repassword', 'compare', 'compareAttribute'=>'password','message'=>'两处输入的密码并不一致'),
    			// 电子邮件验证
    			array('email', 'email'),
    			// 电子邮件唯一性
    			//array('email', 'unique','caseSensitive'=>false,'className'=>'user','message'=>'电子邮件"{value}"已经被注册,请更换'),
    			array('email', 'checkemail'),
    			//array('birthday', 'match', 'pattern'=>'%^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$%', 'allowEmpty'=>true, 'message'=>'生日必须是年-月-日格式'),
    			//array('mobile', 'length', 'max'=>11, 'min'=>11, 'tooLong'=>'手机号码错误','tooShort'=>'手机号码错误'),
                array('verifyCode', 'captcha', 'allowEmpty'=> false),
    		);
    	}
    
    	public function checkname($attribute,$params)
    	{
    		//ucenter
    		Yii::import('application.vendors.*');
    		include_once 'ucenter.php';
    		$flag = uc_user_checkname($this->username);
    		
    		switch($flag)
    		{
    			case -1:
                	$this->addError('username', '用户名不合法');
    				break;
    			case -2:
    				$this->addError('username','包含不允许注册的词语');
    				break;
    			case -3:
    			 	$this->addError('username','用户名已经存在');
    				break;
    		}
    	}
    	
    	public function checkemail($attribute,$params)
    	{
    		//ucenter
    		Yii::import('application.vendors.*');
    		include_once 'ucenter.php';
    		$flag = uc_user_checkemail($this->email);
    
    		switch($flag)
    		{
    			case -4:
                	$this->addError('email', 'Email 格式有误');
    				break;
    			case -5:
    				$this->addError('email','Email 不允许注册');
    				break;
    			case -6:
    			 	$this->addError('email','该 Email 已经被注册');
    				break;
    		}
    	}
    
    	/**
    	 * Declares attribute labels.
    	 */
    	public function attributeLabels()
    	{
    		return array(
                'username'=>'设定用户名',
                'password'=>'设定密码',
    			'repassword'=>'再次输入密码',
    		    'email'=>'电子邮件地址',
    		    'mobile'=>'手机号码',
                'verifyCode'=>'验证码',
    		);
    	}
    
    	/**
    	 * 注册用户
    	 * @return boolean whether register is successful
    	 */
    	public function register($uid)
    	{
    		//ucenter
    		Yii::import('application.vendors.*');
    		include_once 'ucenter.php';
    		$uid = uc_user_register($this->username, $this->password, $this->email);
    		if($uid>0)
    		{
    			$model = new user;
    			$model->attributes = $_POST['RegisterForm'];
    			$model->password = md5($_POST['RegisterForm']['password']);
    			$model->id = $uid;
    			
    			return $model->save();
    		}
    	}
    }
    
    我们看看上面的代码,调用了uc_user_checkname和uc_user_checkemail完成了用户名和email的验证,然后调用了 uc_user_register将用户注册到ucenter,成功后,再注册到Yii应用。
  4. 实现用户登录,典型的Yii应用使用 CUserIdentity来实现登录,我们要做的就是继承它,实现自己的验证逻辑:
    Php代码 复制代码 收藏代码
    1. <?php 
    2.  
    3. /**
    4. * UserIdentity represents the data needed to identity a user.
    5. * It contains the authentication method that checks if the provided
    6. * data can identity the user.
    7. */ 
    8. class UserIdentity extends CUserIdentity 
    9. {    
    10.     public $id
    11.     /**
    12.      * Authenticates a user.
    13.      * The example implementation makes sure if the username and password
    14.      * are both 'demo'.
    15.      * In practical applications, this should be changed to authenticate
    16.      * against some persistent user identity storage (e.g. database).
    17.      * @return boolean whether authentication succeeds.
    18.      */ 
    19.     public function authenticate() 
    20.     { 
    21.         //ucenter 
    22.         Yii::import('application.vendors.*'); 
    23.         include_once 'ucenter.php'
    24.         list($uid, $username, $password, $email) = uc_user_login($this->username, $this->password); 
    25.         if($uid > 0) 
    26.         { 
    27.             $user = user::model()->findByPk($uid); 
    28.              
    29.             if($user == null)//说明网站数据库中没有,而ucenter中有这个用户,添加用户 
    30.             { 
    31.                 $user = new user; 
    32.                 $user->username = $username
    33.                 $user->password = md5($password); 
    34.                 $user->email = $email
    35.                 $user->id = $uid
    36.                 $user->save(); 
    37.                  
    38.                 $user->refresh(); 
    39.             } 
    40.              
    41.             $this->username = $user->username; 
    42.             $this->id = $user->id; 
    43.              
    44.             $user->last_login_time = $user->this_login_time; 
    45.             $user->this_login_time = time(); 
    46.             $user->last_login_ip = $user->this_login_ip; 
    47.             $user->this_login_ip = Yii::app()->getRequest()->userHostAddress; 
    48.             $user->save();  
    49.              
    50.             $this->errorCode=self::ERROR_NONE; 
    51.         } 
    52.         elseif($uid == -1) 
    53.         { 
    54.             $this->errorCode=self::ERROR_USERNAME_INVALID; 
    55.         } 
    56.         elseif($uid == -2) 
    57.         { 
    58.             $this->errorCode=self::ERROR_PASSWORD_INVALID; 
    59.         } 
    60.          
    61.         return !$this->errorCode; 
    62.     } 
    63.      
    64.     public function getId() 
    65.     { 
    66.         return $this->id; 
    67.     } 
    <?php
    
    /**
     * UserIdentity represents the data needed to identity a user.
     * It contains the authentication method that checks if the provided
     * data can identity the user.
     */
    class UserIdentity extends CUserIdentity
    {   
        public $id;
    	/**
    	 * Authenticates a user.
    	 * The example implementation makes sure if the username and password
    	 * are both 'demo'.
    	 * In practical applications, this should be changed to authenticate
    	 * against some persistent user identity storage (e.g. database).
    	 * @return boolean whether authentication succeeds.
    	 */
    	public function authenticate()
    	{
    		//ucenter
    		Yii::import('application.vendors.*');
    		include_once 'ucenter.php';
    		list($uid, $username, $password, $email) = uc_user_login($this->username, $this->password);
    		if($uid > 0)
    		{
    			$user = user::model()->findByPk($uid);
    			
    			if($user == null)//说明网站数据库中没有,而ucenter中有这个用户,添加用户
    			{
    				$user = new user;
    				$user->username = $username;
    				$user->password = md5($password);
    				$user->email = $email;
    				$user->id = $uid;
    				$user->save();
    				
    				$user->refresh();
    			}
    			
                $this->username = $user->username;
                $this->id = $user->id;
    			
                $user->last_login_time = $user->this_login_time;
                $user->this_login_time = time();
                $user->last_login_ip = $user->this_login_ip;
                $user->this_login_ip = Yii::app()->getRequest()->userHostAddress;
                $user->save(); 
    	        
    			$this->errorCode=self::ERROR_NONE;
    		}
    		elseif($uid == -1)
    		{
    			$this->errorCode=self::ERROR_USERNAME_INVALID;
    		}
    		elseif($uid == -2)
    		{
    			$this->errorCode=self::ERROR_PASSWORD_INVALID;
    		}
    	    
    		return !$this->errorCode;
    	}
        
        public function getId()
    	{
    		return $this->id;
    	}
    }
    请根据自己的应用情况进行修改即可,这里我们不需要对Yii的用户登录做任何修改。
  5. 然后我们修改 SiteController/actionLogin 方法,将同步登录其他应用的js输出到浏览器:
    Php代码 复制代码 收藏代码
    1. /**
    2.      * Displays the login page
    3.      */ 
    4.     public function actionLogin() 
    5.     { 
    6.         $model=new LoginForm; 
    7.  
    8.         // if it is ajax validation request 
    9.         if(isset($_POST['ajax']) && $_POST['ajax']==='login-form'
    10.         { 
    11.             echo CActiveForm::validate($model); 
    12.             Yii::app()->end(); 
    13.         } 
    14.  
    15.         // collect user input data 
    16.         if(isset($_POST['LoginForm'])) 
    17.         { 
    18.             $model->attributes=$_POST['LoginForm']; 
    19.             // validate user input and redirect to the previous page if valid 
    20.             if($model->validate() && $model->login()) 
    21.             { 
    22.                 //ucenter 
    23.                 Yii::import('application.vendors.*'); 
    24.                 include_once 'ucenter.php'
    25.                 $script = uc_user_synlogin(Yii::app()->user->id); 
    26.                 $this->render('loginsuc', array
    27.                     'script' => $script
    28.                 )); 
    29.                 Yii::app()->end(); 
    30.             } 
    31.         } 
    32.         // display the login form 
    33.         $this->render('login',array('model'=>$model)); 
    34.     } 
    /**
    	 * Displays the login page
    	 */
    	public function 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())
    			{
    				//ucenter
    				Yii::import('application.vendors.*');
    				include_once 'ucenter.php';
    				$script = uc_user_synlogin(Yii::app()->user->id);
    				$this->render('loginsuc', array(
    					'script' => $script,
    				));
    				Yii::app()->end();
    			}
    		}
    		// display the login form
    		$this->render('login',array('model'=>$model));
    	}
    简单的loginsuc.php视图文件:
    Php代码 复制代码 收藏代码
    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
    3. <head> 
    4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    5. </head> 
    6. <body> 
    7. <?php  
    8. $this->layout = 'none'
    9. echo $script;  
    10. ?> 
    11. <script type="text/javascript">setTimeout('location.href="<?php echo Yii::app()->user->returnUrl ?>"',3000);</script> 
    12. 登录成功,正在返回登录前页面... 
    13. </body> 
    14. </html> 
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
    <?php 
    $this->layout = 'none';
    echo $script; 
    ?>
    <script type="text/javascript">setTimeout('location.href="<?php echo Yii::app()->user->returnUrl ?>"',3000);</script>
    登录成功,正在返回登录前页面...
    </body>
    </html>
  6. 继续修改 SiteController/actionLogout方法,实现同步退出:
    Php代码 复制代码 收藏代码
    1. /**
    2.      * Logs out the current user and redirect to homepage.
    3.      */ 
    4.     public function actionLogout() 
    5.     { 
    6.         Yii::app()->user->logout(); 
    7.         //ucenter 
    8.         Yii::import('application.vendors.*'); 
    9.         include_once 'ucenter.php'
    10.         $script = uc_user_synlogout(); 
    11.         $this->render('logoutsuc', array
    12.             'script' => $script
    13.         )); 
    14.         Yii::app()->end(); 
    15.     } 
    16.      
    /**
    	 * Logs out the current user and redirect to homepage.
    	 */
    	public function actionLogout()
    	{
    		Yii::app()->user->logout();
    		//ucenter
    		Yii::import('application.vendors.*');
    		include_once 'ucenter.php';
    		$script = uc_user_synlogout();
    		$this->render('logoutsuc', array(
    			'script' => $script,
    		));
    		Yii::app()->end();
    	}
        
      简单的logoutsuc.php视图文件:
    Php代码 复制代码 收藏代码
    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
    3. <head> 
    4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    5. </head> 
    6. <body> 
    7. <?php  
    8. $this->layout = 'none'
    9. echo $script;  
    10. ?> 
    11. <script type="text/javascript">setTimeout('location.href="<?php echo Yii::app()->homeUrl ?>"',3000);</script> 
    12. 退出成功,正在返回首页... 
    13. </body> 
    14. </html> 
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
    <?php 
    $this->layout = 'none';
    echo $script; 
    ?>
    <script type="text/javascript">setTimeout('location.href="<?php echo Yii::app()->homeUrl ?>"',3000);</script>
    退出成功,正在返回首页...
    </body>
    </html>

  7. 进行到这里,我们已经实现了整合ucenter的登录和注册了,这样ucenter中有的用户,可以登录到yii应用,yii应用也可以注册用户到ucenter了。但是这还没有完成,我们需要的是在discuz中用户登录时,也同步登录yii应用,退出亦然,那么我们需要实现 Yii应用的 api/uc.php 这个接口程序。由于我们要用到Yii的框架资源,所以我没有采用硬编码的方式实现这个接口,而是创建了一个UcApplication类完成这个任务,继续往下看。
  8. 首先建立 api/uc.php 入口文件,代码如下:
    Php代码 复制代码 收藏代码
    1. <?php 
    2. define('UC_CLIENT_VERSION', '1.6.0'); 
    3. define('UC_CLIENT_RELEASE', '20110501'); 
    4.  
    5. define('API_DELETEUSER', 1);        //note 用户删除 API 接口开关 
    6. define('API_RENAMEUSER', 1);        //note 用户改名 API 接口开关 
    7. define('API_GETTAG', 1);        //note 获取标签 API 接口开关 
    8. define('API_SYNLOGIN', 1);      //note 同步登录 API 接口开关 
    9. define('API_SYNLOGOUT', 1);     //note 同步登出 API 接口开关 
    10. define('API_UPDATEPW', 1);      //note 更改用户密码 开关 
    11. define('API_UPDATEBADWORDS', 1);    //note 更新关键字列表 开关 
    12. define('API_UPDATEHOSTS', 1);       //note 更新域名解析缓存 开关 
    13. define('API_UPDATEAPPS', 1);        //note 更新应用列表 开关 
    14. define('API_UPDATECLIENT', 1);      //note 更新客户端缓存 开关 
    15. define('API_UPDATECREDIT', 1);      //note 更新用户积分 开关 
    16. define('API_GETCREDITSETTINGS', 1); //note 向 UCenter 提供积分设置 开关 
    17. define('API_GETCREDIT', 1);     //note 获取用户的某项积分 开关 
    18. define('API_UPDATECREDITSETTINGS', 1);  //note 更新应用积分设置 开关 
    19.  
    20. define('API_RETURN_SUCCEED', '1'); 
    21. define('API_RETURN_FAILED', '-1'); 
    22. define('API_RETURN_FORBIDDEN', '-2'); 
    23.  
    24. // change the following paths if necessary 
    25. $yii=dirname(__FILE__).'/../protected/yii-1.1.6/framework/yii.php'
    26. $config=dirname(__FILE__).'/../protected/config/main.php'
    27.  
    28. // remove the following lines when in production mode 
    29. defined('YII_DEBUG') or define('YII_DEBUG',true); 
    30. // specify how many levels of call stack should be shown in each log message 
    31. defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',0); 
    32.  
    33. require_once($yii); 
    34. require(dirname(__FILE__).'/../protected/components/UcApplication.php'); 
    35. Yii::createApplication('UcApplication', $config)->run(); 
    <?php
    define('UC_CLIENT_VERSION', '1.6.0');
    define('UC_CLIENT_RELEASE', '20110501');
    
    define('API_DELETEUSER', 1);		//note 用户删除 API 接口开关
    define('API_RENAMEUSER', 1);		//note 用户改名 API 接口开关
    define('API_GETTAG', 1);		//note 获取标签 API 接口开关
    define('API_SYNLOGIN', 1);		//note 同步登录 API 接口开关
    define('API_SYNLOGOUT', 1);		//note 同步登出 API 接口开关
    define('API_UPDATEPW', 1);		//note 更改用户密码 开关
    define('API_UPDATEBADWORDS', 1);	//note 更新关键字列表 开关
    define('API_UPDATEHOSTS', 1);		//note 更新域名解析缓存 开关
    define('API_UPDATEAPPS', 1);		//note 更新应用列表 开关
    define('API_UPDATECLIENT', 1);		//note 更新客户端缓存 开关
    define('API_UPDATECREDIT', 1);		//note 更新用户积分 开关
    define('API_GETCREDITSETTINGS', 1);	//note 向 UCenter 提供积分设置 开关
    define('API_GETCREDIT', 1);		//note 获取用户的某项积分 开关
    define('API_UPDATECREDITSETTINGS', 1);	//note 更新应用积分设置 开关
    
    define('API_RETURN_SUCCEED', '1');
    define('API_RETURN_FAILED', '-1');
    define('API_RETURN_FORBIDDEN', '-2');
    
    // change the following paths if necessary
    $yii=dirname(__FILE__).'/../protected/yii-1.1.6/framework/yii.php';
    $config=dirname(__FILE__).'/../protected/config/main.php';
    
    // remove the following lines when in production mode
    defined('YII_DEBUG') or define('YII_DEBUG',true);
    // specify how many levels of call stack should be shown in each log message
    defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',0);
    
    require_once($yii);
    require(dirname(__FILE__).'/../protected/components/UcApplication.php');
    Yii::createApplication('UcApplication', $config)->run();
    
    这里可以看到,这个脚本和标准的index.php是一样的,只是使用了不同的Application类。我们接着看这个类。
  9. 建立 protected/components/UcApplication.php类文件:
    Php代码 复制代码 收藏代码
    1. <?php 
    2. class UcApplication extends CWebApplication 
    3.     public $defaultController = 'Uc'
    4.      
    5.     private $route = ''
    6.      
    7.     protected function preinit() 
    8.     { 
    9.         $this->parseRequest(); 
    10.     } 
    11.      
    12.     private function parseRequest() 
    13.     { 
    14.         $_DCACHE = $get = $post = array(); 
    15.  
    16.         $code = @$_GET['code']; 
    17.         parse_str($this->_authcode($code, 'DECODE', UC_KEY), $get); 
    18.         if(MAGIC_QUOTES_GPC) { 
    19.             $get = $this->_stripslashes($get); 
    20.         } 
    21.          
    22.         $timestamp = time(); 
    23.         if($timestamp - $get['time'] > 3600) { 
    24.             //exit('Authracation has expiried'); 
    25.         } 
    26.         if(emptyempty($get)) { 
    27.             exit('Invalid Request'); 
    28.         } 
    29.         $action = $get['action']; 
    30.          
    31.         require_once 'xml.class.php'
    32.         $post = xml_unserialize(file_get_contents('php://input')); 
    33.         Yii::log($get, 'debug'); 
    34.         Yii::log($post, 'debug'); 
    35.         $_GET = $get
    36.         $_POST = $post
    37.          
    38.         $this->route = $this->defaultController .'/'. $action
    39.          
    40.         if(!in_array($action, array('test', 'deleteuser', 'renameuser', 'gettag', 'synlogin', 'synlogout', 'updatepw', 'updatebadwords', 'updatehosts', 'updateapps', 'updateclient', 'updatecredit', 'getcreditsettings', 'updatecreditsettings')))  
    41.         { 
    42.             exit(API_RETURN_FAILED); 
    43.         } 
    44.     } 
    45.      
    46.     public function processRequest() 
    47.     { 
    48.         $this->runController($this->route); 
    49.     } 
    50.      
    51.     private function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { 
    52.         $ckey_length = 4; 
    53.      
    54.         $key = md5($key ? $key : UC_KEY); 
    55.         $keya = md5(substr($key, 0, 16)); 
    56.         $keyb = md5(substr($key, 16, 16)); 
    57.         $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''
    58.      
    59.         $cryptkey = $keya.md5($keya.$keyc); 
    60.         $key_length = strlen($cryptkey); 
    61.      
    62.         $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string
    63.         $string_length = strlen($string); 
    64.      
    65.         $result = ''
    66.         $box = range(0, 255); 
    67.      
    68.         $rndkey = array(); 
    69.         for($i = 0; $i <= 255; $i++) { 
    70.             $rndkey[$i] = ord($cryptkey[$i % $key_length]); 
    71.         } 
    72.      
    73.         for($j = $i = 0; $i < 256; $i++) { 
    74.             $j = ($j + $box[$i] + $rndkey[$i]) % 256; 
    75.             $tmp = $box[$i]; 
    76.             $box[$i] = $box[$j]; 
    77.             $box[$j] = $tmp
    78.         } 
    79.      
    80.         for($a = $j = $i = 0; $i < $string_length; $i++) { 
    81.             $a = ($a + 1) % 256; 
    82.             $j = ($j + $box[$a]) % 256; 
    83.             $tmp = $box[$a]; 
    84.             $box[$a] = $box[$j]; 
    85.             $box[$j] = $tmp
    86.             $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); 
    87.         } 
    88.      
    89.         if($operation == 'DECODE') { 
    90.             if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { 
    91.                 return substr($result, 26); 
    92.             } else
    93.                     return ''
    94.                 } 
    95.         } else
    96.             return $keyc.str_replace('=', '', base64_encode($result)); 
    97.         } 
    98.      
    99.     } 
    100.  
    101.     private function _stripslashes($string) { 
    102.         if(is_array($string)) { 
    103.             foreach($string as $key => $val) { 
    104.                 $string[$key] = $this->_stripslashes($val); 
    105.             } 
    106.         } else
    107.             $string = stripslashes($string); 
    108.         } 
    109.         return $string
    110.     } 
    <?php
    class UcApplication extends CWebApplication
    {
    	public $defaultController = 'Uc';
    	
    	private $route = '';
    	
    	protected function preinit()
    	{
            $this->parseRequest();
        }
    	
    	private function parseRequest()
    	{
    		$_DCACHE = $get = $post = array();
    
    		$code = @$_GET['code'];
    		parse_str($this->_authcode($code, 'DECODE', UC_KEY), $get);
    		if(MAGIC_QUOTES_GPC) {
    			$get = $this->_stripslashes($get);
    		}
    		
    		$timestamp = time();
    		if($timestamp - $get['time'] > 3600) {
    			//exit('Authracation has expiried');
    		}
    		if(empty($get)) {
    			exit('Invalid Request');
    		}
    		$action = $get['action'];
    		
    		require_once 'xml.class.php';
    		$post = xml_unserialize(file_get_contents('php://input'));
    		Yii::log($get, 'debug');
    		Yii::log($post, 'debug');
    		$_GET = $get;
    		$_POST = $post;
    		
    		$this->route = $this->defaultController .'/'. $action;
    		
    		if(!in_array($action, array('test', 'deleteuser', 'renameuser', 'gettag', 'synlogin', 'synlogout', 'updatepw', 'updatebadwords', 'updatehosts', 'updateapps', 'updateclient', 'updatecredit', 'getcreditsettings', 'updatecreditsettings'))) 
    		{
    			exit(API_RETURN_FAILED);
    		}
    	}
        
        public function processRequest()
    	{
    		$this->runController($this->route);
    	}
    	
    	private function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    		$ckey_length = 4;
    	
    		$key = md5($key ? $key : UC_KEY);
    		$keya = md5(substr($key, 0, 16));
    		$keyb = md5(substr($key, 16, 16));
    		$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
    	
    		$cryptkey = $keya.md5($keya.$keyc);
    		$key_length = strlen($cryptkey);
    	
    		$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
    		$string_length = strlen($string);
    	
    		$result = '';
    		$box = range(0, 255);
    	
    		$rndkey = array();
    		for($i = 0; $i <= 255; $i++) {
    			$rndkey[$i] = ord($cryptkey[$i % $key_length]);
    		}
    	
    		for($j = $i = 0; $i < 256; $i++) {
    			$j = ($j + $box[$i] + $rndkey[$i]) % 256;
    			$tmp = $box[$i];
    			$box[$i] = $box[$j];
    			$box[$j] = $tmp;
    		}
    	
    		for($a = $j = $i = 0; $i < $string_length; $i++) {
    			$a = ($a + 1) % 256;
    			$j = ($j + $box[$a]) % 256;
    			$tmp = $box[$a];
    			$box[$a] = $box[$j];
    			$box[$j] = $tmp;
    			$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    		}
    	
    		if($operation == 'DECODE') {
    			if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
    				return substr($result, 26);
    			} else {
    					return '';
    				}
    		} else {
    			return $keyc.str_replace('=', '', base64_encode($result));
    		}
    	
    	}
    
    	private function _stripslashes($string) {
    		if(is_array($string)) {
    			foreach($string as $key => $val) {
    				$string[$key] = $this->_stripslashes($val);
    			}
    		} else {
    			$string = stripslashes($string);
    		}
    		return $string;
    	}
    }
    
    这里可以看到,主要逻辑是processRequest方法,实现了ucenter通知的解码、调用相应的控制器和动作实现操作。
  10. 然后建立 protected/controller/UcController.php文件,代码如下:
    Php代码 复制代码 收藏代码
    1. <?php 
    2. class UcController extends Controller 
    3.     private $appdir = ''
    4.      
    5.     protected function beforeAction(CAction $action
    6.     { 
    7.         $this->appdir = Yii::app()->basePath . '/vendors/'
    8.         return parent::beforeAction($action); 
    9.     } 
    10.      
    11.     public function actionTest() { 
    12.         echo API_RETURN_SUCCEED; 
    13.     } 
    14.  
    15.     public function actionDeleteuser() { 
    16.         $uids = explode(',', str_replace("'", '', $_GET['ids'])); 
    17.         !API_DELETEUSER && exit(API_RETURN_FORBIDDEN); 
    18.          
    19.         $users = user::model()->findAllByPk($uids); 
    20.         foreach($users as $user
    21.         { 
    22.             $user->delete(); 
    23.         } 
    24.  
    25.         echo API_RETURN_SUCCEED; 
    26.     } 
    27.  
    28.     public function actionRenameuser() { 
    29.         $uid = $_GET['uid']; 
    30.         $usernameold = $_GET['oldusername']; 
    31.         $usernamenew = $_GET['newusername']; 
    32.         if(!API_RENAMEUSER) { 
    33.             echo API_RETURN_FORBIDDEN; 
    34.         } 
    35.          
    36.         $user = user::model()->findByPk($uid); 
    37.         if($user !== null) 
    38.         { 
    39.             $user->username = $usernamenew
    40.             if($user->save(false)) 
    41.                 echo API_RETURN_SUCCEED; 
    42.             else 
    43.                 echo API_RETURN_FAILED; 
    44.         } 
    45.     } 
    46.  
    47.     public function actionGettag() { 
    48.         $name = $_GET['id']; 
    49.         if(!API_GETTAG) { 
    50.             echo API_RETURN_FORBIDDEN; 
    51.         } 
    52.          
    53.         $echo = array(); 
    54.         echo $this->_serialize($return, 1); 
    55.     } 
    56.  
    57.     public function actionSynlogin() { 
    58.         $uid = $_GET['uid']; 
    59.         $username = $_GET['username']; 
    60.         if(!API_SYNLOGIN) { 
    61.             echo API_RETURN_FORBIDDEN; 
    62.         } 
    63.          
    64.         $identity=new UcUserIdentity($username); 
    65.  
    66.         if($identity->authenticate()) 
    67.         { 
    68.             Yii::app()->user->login($identity, 0); 
    69.         } 
    70.  
    71.         header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); 
    72.         //$_SESSION[Yii::app()->user->stateKeyPrefix.'__id'] = $uid; 
    73.         //$_SESSION[Yii::app()->user->stateKeyPrefix.'__name'] = $username; 
    74.     } 
    75.  
    76.     public function actionSynlogout() { 
    77.         if(!API_SYNLOGOUT) { 
    78.             echo API_RETURN_FORBIDDEN; 
    79.         } 
    80.  
    81.         //note 同步登出 API 接口 
    82.         header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); 
    83.         Yii::app()->user->logout(); 
    84.     } 
    85.  
    86.     public function actionUpdatepw() { 
    87.         if(!API_UPDATEPW) { 
    88.             echo API_RETURN_FORBIDDEN; 
    89.         } 
    90.         $username = $_GET['username']; 
    91.         $password = $_GET['password']; 
    92.          
    93.         $user = user::model()->findByAttributes(array('username'=>$username)); 
    94.         if($user !== null) 
    95.         { 
    96.             $user->password = md5($password); 
    97.             if($user->save()) 
    98.                 echo API_RETURN_SUCCEED; 
    99.             else 
    100.                 echo API_RETURN_FAILED; 
    101.         } 
    102.         else 
    103.             echo API_RETURN_FAILED; 
    104.     } 
    105.  
    106.     public function actionUpdatebadwords() { 
    107.         if(!API_UPDATEBADWORDS) { 
    108.             echo API_RETURN_FORBIDDEN; 
    109.         } 
    110.         $cachefile = $this->appdir.'./uc_client/data/cache/badwords.php'
    111.         $fp = fopen($cachefile, 'w'); 
    112.         $data = array(); 
    113.         if(is_array($_POST)) { 
    114.             foreach($_POST as $k => $v) { 
    115.                 $data['findpattern'][$k] = $v['findpattern']; 
    116.                 $data['replace'][$k] = $v['replacement']; 
    117.             } 
    118.         } 
    119.         $s = "<?php\r\n"
    120.         $s .= '$_CACHE[\'badwords\'] = '.var_export($data, TRUE).";\r\n"
    121.         fwrite($fp, $s); 
    122.         fclose($fp); 
    123.         echo API_RETURN_SUCCEED; 
    124.     } 
    125.  
    126.     public function actionUpdatehosts() { 
    127.         if(!API_UPDATEHOSTS) { 
    128.             echo API_RETURN_FORBIDDEN; 
    129.         } 
    130.         $cachefile = $this->appdir.'./uc_client/data/cache/hosts.php'
    131.         $fp = fopen($cachefile, 'w'); 
    132.         $s = "<?php\r\n"
    133.         $s .= '$_CACHE[\'hosts\'] = '.var_export($_POST, TRUE).";\r\n"
    134.         fwrite($fp, $s); 
    135.         fclose($fp); 
    136.         echo API_RETURN_SUCCEED; 
    137.     } 
    138.  
    139.     public function actionUpdateapps() { 
    140.         if(!API_UPDATEAPPS) { 
    141.             echo API_RETURN_FORBIDDEN; 
    142.         } 
    143.         $UC_API = $_POST['UC_API']; 
    144.  
    145.         //note 写 app 缓存文件 
    146.         $cachefile = $this->appdir.'./uc_client/data/cache/apps.php'
    147.         $fp = fopen($cachefile, 'w'); 
    148.         $s = "<?php\r\n"
    149.         $s .= '$_CACHE[\'apps\'] = '.var_export($_POST, TRUE).";\r\n"
    150.         fwrite($fp, $s); 
    151.         fclose($fp); 
    152.  
    153.         //note 写配置文件 
    154.         $config_file = Yii::app()->basePath.'./config/main.php'
    155.         if(is_writeable($config_file)) { 
    156.             $configfile = trim(file_get_contents($config_file)); 
    157.             $configfile = substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) : $configfile
    158.             $configfile = preg_replace("/define\('UC_API',\s*'.*?'\);/i", "define('UC_API', '$UC_API');", $configfile); 
    159.             if($fp = @fopen($config_file, 'w')) { 
    160.                 @fwrite($fp, trim($configfile)); 
    161.                 @fclose($fp); 
    162.             } 
    163.         } 
    164.      
    165.         echo API_RETURN_SUCCEED; 
    166.     } 
    167.  
    168.     public function actionUpdateclient() { 
    169.         if(!API_UPDATECLIENT) { 
    170.             echo API_RETURN_FORBIDDEN; 
    171.         } 
    172.         $cachefile = $this->appdir.'./uc_client/data/cache/settings.php'
    173.         $fp = fopen($cachefile, 'w'); 
    174.         $s = "<?php\r\n"
    175.         $s .= '$_CACHE[\'settings\'] = '.var_export($_POST, TRUE).";\r\n"
    176.         fwrite($fp, $s); 
    177.         fclose($fp); 
    178.         echo API_RETURN_SUCCEED; 
    179.     } 
    180.  
    181.     public function actionUpdatecredit() { 
    182.         if(!API_UPDATECREDIT) { 
    183.             echo API_RETURN_FORBIDDEN; 
    184.         } 
    185.         $credit = $_GET['credit']; 
    186.         $amount = $_GET['amount']; 
    187.         $uid = $_GET['uid']; 
    188.         echo API_RETURN_SUCCEED; 
    189.     } 
    190.  
    191.     public function actionGetcredit() { 
    192.         if(!API_GETCREDIT) { 
    193.             echo API_RETURN_FORBIDDEN; 
    194.         } 
    195.     } 
    196.  
    197.     public function actionGetcreditsettings() { 
    198.         if(!API_GETCREDITSETTINGS) { 
    199.             echo API_RETURN_FORBIDDEN; 
    200.         } 
    201.         $credits = array(); 
    202.         echo $this->_serialize($credits); 
    203.     } 
    204.  
    205.     public function actionUpdatecreditsettings() { 
    206.         if(!API_UPDATECREDITSETTINGS) { 
    207.             echo API_RETURN_FORBIDDEN; 
    208.         } 
    209.         echo API_RETURN_SUCCEED; 
    210.     } 
    211.      
    212.     private function _serialize($arr, $htmlon = 0) { 
    213.         if(!function_exists('xml_serialize')) { 
    214.             include_once 'xml.class.php'
    215.         } 
    216.         echo xml_serialize($arr, $htmlon); 
    217.     } 
    <?php
    class UcController extends Controller
    {
    	private $appdir = '';
    	
    	protected function beforeAction(CAction $action)
    	{
    		$this->appdir = Yii::app()->basePath . '/vendors/';
    		return parent::beforeAction($action);
    	}
    	
    	public function actionTest() {
    		echo API_RETURN_SUCCEED;
    	}
    
    	public function actionDeleteuser() {
    		$uids = explode(',', str_replace("'", '', $_GET['ids']));
    		!API_DELETEUSER && exit(API_RETURN_FORBIDDEN);
    		
    		$users = user::model()->findAllByPk($uids);
    		foreach($users as $user)
    		{
    			$user->delete();
    		}
    
    		echo API_RETURN_SUCCEED;
    	}
    
    	public function actionRenameuser() {
    		$uid = $_GET['uid'];
    		$usernameold = $_GET['oldusername'];
    		$usernamenew = $_GET['newusername'];
    		if(!API_RENAMEUSER) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		
    		$user = user::model()->findByPk($uid);
    		if($user !== null)
    		{
    			$user->username = $usernamenew;
    			if($user->save(false))
    				echo API_RETURN_SUCCEED;
    			else
    				echo API_RETURN_FAILED;
    		}
    	}
    
    	public function actionGettag() {
    		$name = $_GET['id'];
    		if(!API_GETTAG) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		
    		$echo = array();
    		echo $this->_serialize($return, 1);
    	}
    
    	public function actionSynlogin() {
    		$uid = $_GET['uid'];
    		$username = $_GET['username'];
    		if(!API_SYNLOGIN) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		
    		$identity=new UcUserIdentity($username);
    
    		if($identity->authenticate())
    		{
    			Yii::app()->user->login($identity, 0);
    		}
    
    		header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
    		//$_SESSION[Yii::app()->user->stateKeyPrefix.'__id'] = $uid;
    		//$_SESSION[Yii::app()->user->stateKeyPrefix.'__name'] = $username;
    	}
    
    	public function actionSynlogout() {
    		if(!API_SYNLOGOUT) {
    			echo API_RETURN_FORBIDDEN;
    		}
    
    		//note 同步登出 API 接口
    		header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
    		Yii::app()->user->logout();
    	}
    
    	public function actionUpdatepw() {
    		if(!API_UPDATEPW) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		$username = $_GET['username'];
    		$password = $_GET['password'];
    		
    		$user = user::model()->findByAttributes(array('username'=>$username));
    		if($user !== null)
    		{
    			$user->password = md5($password);
    			if($user->save())
    				echo API_RETURN_SUCCEED;
    			else
    				echo API_RETURN_FAILED;
    		}
    		else
    			echo API_RETURN_FAILED;
    	}
    
    	public function actionUpdatebadwords() {
    		if(!API_UPDATEBADWORDS) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		$cachefile = $this->appdir.'./uc_client/data/cache/badwords.php';
    		$fp = fopen($cachefile, 'w');
    		$data = array();
    		if(is_array($_POST)) {
    			foreach($_POST as $k => $v) {
    				$data['findpattern'][$k] = $v['findpattern'];
    				$data['replace'][$k] = $v['replacement'];
    			}
    		}
    		$s = "<?php\r\n";
    		$s .= '$_CACHE[\'badwords\'] = '.var_export($data, TRUE).";\r\n";
    		fwrite($fp, $s);
    		fclose($fp);
    		echo API_RETURN_SUCCEED;
    	}
    
    	public function actionUpdatehosts() {
    		if(!API_UPDATEHOSTS) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		$cachefile = $this->appdir.'./uc_client/data/cache/hosts.php';
    		$fp = fopen($cachefile, 'w');
    		$s = "<?php\r\n";
    		$s .= '$_CACHE[\'hosts\'] = '.var_export($_POST, TRUE).";\r\n";
    		fwrite($fp, $s);
    		fclose($fp);
    		echo API_RETURN_SUCCEED;
    	}
    
    	public function actionUpdateapps() {
    		if(!API_UPDATEAPPS) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		$UC_API = $_POST['UC_API'];
    
    		//note 写 app 缓存文件
    		$cachefile = $this->appdir.'./uc_client/data/cache/apps.php';
    		$fp = fopen($cachefile, 'w');
    		$s = "<?php\r\n";
    		$s .= '$_CACHE[\'apps\'] = '.var_export($_POST, TRUE).";\r\n";
    		fwrite($fp, $s);
    		fclose($fp);
    
    		//note 写配置文件
    		$config_file = Yii::app()->basePath.'./config/main.php';
    		if(is_writeable($config_file)) {
    			$configfile = trim(file_get_contents($config_file));
    			$configfile = substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) : $configfile;
    			$configfile = preg_replace("/define\('UC_API',\s*'.*?'\);/i", "define('UC_API', '$UC_API');", $configfile);
    			if($fp = @fopen($config_file, 'w')) {
    				@fwrite($fp, trim($configfile));
    				@fclose($fp);
    			}
    		}
    	
    		echo API_RETURN_SUCCEED;
    	}
    
    	public function actionUpdateclient() {
    		if(!API_UPDATECLIENT) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		$cachefile = $this->appdir.'./uc_client/data/cache/settings.php';
    		$fp = fopen($cachefile, 'w');
    		$s = "<?php\r\n";
    		$s .= '$_CACHE[\'settings\'] = '.var_export($_POST, TRUE).";\r\n";
    		fwrite($fp, $s);
    		fclose($fp);
    		echo API_RETURN_SUCCEED;
    	}
    
    	public function actionUpdatecredit() {
    		if(!API_UPDATECREDIT) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		$credit = $_GET['credit'];
    		$amount = $_GET['amount'];
    		$uid = $_GET['uid'];
    		echo API_RETURN_SUCCEED;
    	}
    
    	public function actionGetcredit() {
    		if(!API_GETCREDIT) {
    			echo API_RETURN_FORBIDDEN;
    		}
    	}
    
    	public function actionGetcreditsettings() {
    		if(!API_GETCREDITSETTINGS) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		$credits = array();
    		echo $this->_serialize($credits);
    	}
    
    	public function actionUpdatecreditsettings() {
    		if(!API_UPDATECREDITSETTINGS) {
    			echo API_RETURN_FORBIDDEN;
    		}
    		echo API_RETURN_SUCCEED;
    	}
    	
    	private function _serialize($arr, $htmlon = 0) {
    		if(!function_exists('xml_serialize')) {
    			include_once 'xml.class.php';
    		}
    		echo xml_serialize($arr, $htmlon);
    	}
    }
    

    上面用到了xml.class.php这个类文件,可以在uc_client/lib目录找到。
    这里需要说明的是,actionSynlogin方法中,利用了我定义的特殊的UserIdentity来登录的,因为不需要提供密码。
  11. 再来看看最后一个类:
    Php代码 复制代码 收藏代码
    1. <?php 
    2.  
    3. /**
    4. * UserIdentity represents the data needed to identity a user.
    5. * It contains the authentication method that checks if the provided
    6. * data can identity the user.
    7. */ 
    8. class UcUserIdentity extends CUserIdentity 
    9. {    
    10.     public $id
    11.      
    12.     /**
    13.      * Constructor.
    14.      * @param string $username username
    15.      */ 
    16.     public function __construct($username
    17.     { 
    18.         $this->username=$username
    19.         $this->password=''
    20.     } 
    21.     /**
    22.      * Authenticates a user.
    23.      * The example implementation makes sure if the username and password
    24.      * are both 'demo'.
    25.      * In practical applications, this should be changed to authenticate
    26.      * against some persistent user identity storage (e.g. database).
    27.      * @return boolean whether authentication succeeds.
    28.      */ 
    29.     public function authenticate() 
    30.     { 
    31.         $user = user::model()->findByAttributes(array('username'=>$this->username)); 
    32.          
    33.         if($user == null)//说明网站数据库中没有,而ucenter中有这个用户,添加用户 
    34.         { 
    35.             //ucenter 
    36.             Yii::import('application.vendors.*'); 
    37.             include_once 'ucenter.php'
    38.             list($uid, $username, $email) = uc_get_user($this->username); 
    39.             if($uid
    40.             { 
    41.                 $user = new user; 
    42.                 $user->username = $username
    43.                 $user->password = md5(rand(10000,99999)); 
    44.                 $user->email = $email
    45.                 $user->id = $uid
    46.                 $user->save(); 
    47.                  
    48.                 $user->refresh(); 
    49.             } 
    50.         } 
    51.          
    52.         $this->id = $user->id; 
    53.          
    54.         $user->last_login_time = $user->this_login_time; 
    55.         $user->this_login_time = time(); 
    56.         $user->last_login_ip = $user->this_login_ip; 
    57.         $user->this_login_ip = Yii::app()->getRequest()->userHostAddress; 
    58.         $user->save();  
    59.          
    60.         $this->errorCode=self::ERROR_NONE; 
    61.          
    62.         return !$this->errorCode; 
    63.     } 
    64.      
    65.     public function getId() 
    66.     { 
    67.         return $this->id; 
    68.     } 
    <?php
    
    /**
     * UserIdentity represents the data needed to identity a user.
     * It contains the authentication method that checks if the provided
     * data can identity the user.
     */
    class UcUserIdentity extends CUserIdentity
    {   
        public $id;
    	
    	/**
    	 * Constructor.
    	 * @param string $username username
    	 */
    	public function __construct($username)
    	{
    		$this->username=$username;
    		$this->password='';
    	}
    	/**
    	 * Authenticates a user.
    	 * The example implementation makes sure if the username and password
    	 * are both 'demo'.
    	 * In practical applications, this should be changed to authenticate
    	 * against some persistent user identity storage (e.g. database).
    	 * @return boolean whether authentication succeeds.
    	 */
    	public function authenticate()
    	{
    		$user = user::model()->findByAttributes(array('username'=>$this->username));
    		
    		if($user == null)//说明网站数据库中没有,而ucenter中有这个用户,添加用户
    		{
    			//ucenter
    			Yii::import('application.vendors.*');
    			include_once 'ucenter.php';
    			list($uid, $username, $email) = uc_get_user($this->username);
    			if($uid)
    			{
    				$user = new user;
    				$user->username = $username;
    				$user->password = md5(rand(10000,99999));
    				$user->email = $email;
    				$user->id = $uid;
    				$user->save();
    				
    				$user->refresh();
    			}
    		}
    		
            $this->id = $user->id;
    		
            $user->last_login_time = $user->this_login_time;
            $user->this_login_time = time();
            $user->last_login_ip = $user->this_login_ip;
            $user->this_login_ip = Yii::app()->getRequest()->userHostAddress;
            $user->save(); 
    	    
    		$this->errorCode=self::ERROR_NONE;
    		
    		return !$this->errorCode;
    	}
        
        public function getId()
    	{
    		return $this->id;
    	}
    }
    可以看到,在这个认证类中,实现了对yii应用中没有的用户的建立操作。然后不需要对yii应用做任何特殊设置,就可以实现api接口了。
  12. 然后我们在ucenter中添加yii应用的设置,修改main.php中的相应设置,应该就可以实现ucenter的同步登录、注册、退出、删除用户、修改用户名等等功能了!这个实现方法相对很Yii,呵呵。

有什么问题,欢迎评论,和我联系。大家一起进步吧!

PS: 需要注意的是,整合了ucenter的Yii应用在部署时,需将 protected/vendors/uc_client/data/及其子目录、文件设为可写。否则将会有些奇怪的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值