整合symfony项目到康盛ucenter系列产品中

September 9, 2009 – 6:28 pm

最近开发一个使用symfony框架的产品,并且需要把这个项目作为一个应用添加到ucenter系列产品中,以前做过的都是康盛家族产品的整合和二次开发,还没有试验过把php框架开发的项目整合到ucenter中,整合的过程就记录在这里了。
(以下实验基于symfony1.2.7,ucenter1.0,uchome1.5版本)

康盛官方提供了一个ucenter开发包,里面包含一份电子版手册,一个uc客户端软件包,还有一个实例程序包。实际上我们现在要整合symfony项目到ucenter中,就是把实例程序改写成symfony框架程序格式,然后调用uc客户端软件包即可实现。那么首先,我们分析一下ucenter的通讯机制。

登录ucenter管理界面,只要你点击了“应用管理”选项卡,ucenter就会分别发出对应的请求给应用项目来测试通讯是否通畅。例如,我们安装了ucenter和uchome两个产品,那么ucenter就发出一个请求给uchome,uchome项目里的通讯客户端程序接受请求并返回一个常量API_RETURN_SUCCEED,如此即为我们看到的“通讯成功”。具体可以通过抓包分析并阅读ucenter的源代码查看细节。

以登录同步为例,假如我们安装了ucenter、uchome和discuz三个产品,现在我们访问uchome并登录,同步登录机制会同时让discuz的用户会话写入,即我们看到的同步登录实现。访问实例程序并抓包试验一下,原来客户端软件包在登录时通过与ucenter通讯获取了js代码,来发送登录请求给其他项目,即uchome登录时,uchome自己写入了会话,同时通js发送请求给discuz的通讯客户端程序,discuz的通讯客户端程序在验证是同步登录请求后,把会话写入了当前浏览器,由此实现了同步登录。
明白了这些基本原理,我们后面的工作就是把这套实现机制引入symfony程序了。

开发流程:

1.定义symfony路由规则
在routing.yml里加入如下代码:
url: /api/uc.php
param: { module: sync, action: ping }
url: /login
param: { module: sync, action: login }

2.构建module和action
创建sync模块和两个动作ping和login

3.加入uc客户端软件包,加入相应类文件
把client通讯包拷贝到项目lib目录下,把以下配置代码加到client.php中:

  1. // 与 UCenter 的通信密钥, 要与 UCenter 保持一致
  2. define('UC_KEY', sfConfig::get('app_ucenter_key'));
  3. // UCenter 的 IP
  4. define('UC_IP', '');
  5. //同步登录 Cookie 设置
  6. define('UC_CHARSET', 'utf8');// UCenter 的字符集
  7. $cookiedomain = '';// cookie 作用域
  8. $cookiepath = '/';// cookie 作用路径
  9. //center的url地址
  10. define('UC_API',sfConfig::get('app_center_url'));

把实例程序包api/uc.php中的方法authcode()封装成一个类放到apps/frontend/lib下,注意通讯密钥要被authcode()访问到

4.开发动作代码
首先写通讯代码,pingAction.class.php代码如下:

  1. <?php
  2. class pingAction extends sfAction
  3. {
  4.   public function execute($request)
  5.   {
  6.     $code = $request->getParameter('code');
  7.     $uc = new ucenter();
  8.     parse_str($uc->authcode($code, 'DECODE'), $get);
  9.     if(time() - $get['time'] > 3600)
  10.     {
  11.       exit('Authracation has expiried');
  12.     }
  13.     if(empty($get))
  14.     {
  15.       exit('Invalid Request');
  16.     }
  17.     $action = $get['action'];
  18.     if ("test" == $action)
  19.     {
  20.       $this->test();
  21.     }
  22.     elseif ("synlogin" == $action)
  23.     {
  24.       $this->synlogin($get['uid']);
  25.     }
  26.     exit();
  27.   }
  28.   private function test()
  29.   {
  30.     return $this->renderText(sfConfig::get('app_ping_succeed'));
  31.   }
  32.   private function synlogin($uid)
  33.   {
  34.     return $this->getUser()->setAttribute('memberID',$uid);
  35.   }
  36. }

清除symfony缓存后访问center,即可看到通讯成功,如图片:

ping ucenter

继续写同步登录代码,loginAction.class.php代码如下:

  1. <?php
  2. class loginAction extends sfAction
  3. {
  4.   public function execute($request)
  5.   {
  6.     if ($request->getMethod == "POST")
  7.     {
  8.       $loginName = $request->getParameter('loginName');
  9.       $passwd = $request->getParameter('passwd');
  10.       include_once(sfConfig::get('sf_lib_dir')."/client/client.php");
  11.       list($uid, $username, $password, $email) = uc_user_login($loginName, $passwd);
  12.       if ($uid > 0)
  13.       {
  14.         $this->getUser()->setAttribute('memberID',$uid);
  15.         $ucsynloginCode = uc_user_synlogin($uid);
  16.         echo '登录成功';
  17.         echo $ucsynloginCode;
  18.         echo '<a href="/login">继续</a>';
  19.       }
  20.       elseif ($uid == -1)
  21.       {
  22.         echo "登录用户名不存在";
  23.         echo '<a href="/login">重新登录</a>';
  24.       }
  25.       elseif ($uid == -2)
  26.       {
  27.         echo "密码不正确";
  28.         echo '<a href="/login">重新登录</a>';
  29.       }
  30.       else
  31.       {
  32.         echo "其他情况";
  33.       }
  34.       exit();
  35.     }
  36.     return sfView::SUCCESS;
  37.   }
  38. }

模板loginSuccess.php代码如下:
<?php if ($sf_user->hasAttribute(’memberID’)): ?>
登录成功!
<?php else: ??>
<form method=”POST” action=”/login”>
<input type=”text” name=”loginName” />
<input type=”password” name=”passwd” />
<input type=”submit” value=”登录” />
</from>
<?php endif; ?>
测试一下,当symfony程序登录后,通过center同步登录机制,uchome也实现了同步登录,同理,你从。其他例如登出,注册,短消息操作均可以参考center开发手册进行。
分析一下康盛center同步登录机制,如果只有三五个项目在通过center实现同步登录,那么此技术结构应该是可以接受的,不过如果有十个以上的项目需要进行同步登录,这套技术结构就显得有点效率低,我们就需要想别的方法实现通行证方案了。

Post a Comment