上回说到在服务端出现通信成功 代表很重要的一步已经搞定了,可能在这个步骤中会出现很多坑,这里说几点
1.在nginx可能会出现显示一直正在连接中,导致后台卡死,百度过后这是在windins中的现象,换apache解决
2.出现通信失败一般的原因是key没有正确配置导致,注意检查每个客户端中的key是否和服务端中的配置一样
3.还有就是在他官方的示例代码中,有处代码错误,大致是没有配置数据库,会报错,大家找到加上就可以
服务端向客户端通信步骤
在阅读discuz源码后发现他实现同步登录其实就是调用uc_user_synlogin函数来生成一堆script代码,这些代码中src都是你服务端配置的各个应用的url/api.uc.php(在示例代码中更加容易看到)
uc_user_synlogin() 这个函数 代表着 要同步登陆到其他所有开启同步登陆的函数 uc自己会在后台把所有开启同步登陆的应用都给循环遍历一遍 然后 在页面上输出
<script type=”text/javascript” src=”xxxxxxxxxxxxxxxxxxxxxxxxx” reload=”1″></script>
<script type=”text/javascript” src=”xxxxxxxxxxxxxxxxxxxxxxxxx” reload=”1″></script>
发送给每个开启同步登陆的应用, 然后每个开启同步登陆的应用的回调文件 uc.php 接受到后会进行解密,解密好后其实你就可以自己来写代码了
这个图大家应该可以看的更加清楚,这是示例代码的例子:
然后我们在客户端uc.php中 执行自己逻辑,包含生成token、cookie之类的,下面示例代码是thinkphp5框架的大家可以参考
//------------------------------------引入thinphp核心文件完成登录状态---------------------------------------- // 引入核心文件 require_once '../../simplewind/thinkphp/base.php'; // 生成token文件 require_once '../../app/common/logic/AuthManager.php'; // 公共函数文件 require_once '../../app/common.php'; // 助手函数 require_once '../../simplewind/thinkphp/helper.php'; $bbs=\think\Db::connect([ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => 'xxxxx', // 数据库名 'database' => 'xxxx', // 数据库用户名 'username' => 'xxx', // 数据库密码 'password' => 'xxxx', // 数据库编码默认采用utf8 'charset' => 'utf8', // 数据库表前缀 'prefix' => 'pre_common_', ]); $res=$bbs->table('pre_ucenter_members')->where('uid',1)->field('uid,username')->find(); $res['sid']=\app\common\logic\AuthManager::createKey('User',$res); setcookie('info',json_encode($res),time()+86400,'/','.yingyin.com'); //----------------------end--------------------------
这里生成cookie 域名是.yingyin.com,这样设置是为了让我们cookie达到跨域效果
接下来在我们单页应用中 就可以通过判断这个cookie 来达到是否登录的目的
客户端向服务端通信步骤
只要弄明白服务端向客户端通信,这个就简单了
原理就是在我们登录接口中,使用uc_user_synlogin函数来生成通知代码,然后返回到网站上,网站通过接口拿到通知然后进行进行异步通知即可
大致代码如下
//---------------------------登录通知_beg-------------------------------------------- include_once CMF_ROOT.'/public/config.inc.php'; include_once CMF_ROOT.'/public/include/db_mysql.class.php'; include_once CMF_ROOT.'/public/uc_client/client.php'; //用户登陆成功,设置 Cookie,加密直接用 uc_authcode 函数,用户使用自己的函数 setcookie('Example_auth', uc_authcode($res['uid']."\t".$res['username'], 'ENCODE')); setcookie('Example_auth', '', -86400); //生成同步登录的代码 $ucsynlogin = uc_user_synlogin($res['uid']); if (preg_match_all('/"http(.+?)"/', $ucsynlogin, $matches)) { foreach ($matches[0] as $k=>$v){ $res['synlogin'][]=str_replace('"','',$v); } } //---------------------------登录通知_end--------------------------------------------
最后说
这个流程只是本人对ucenter的一些了解,当然可能不是最简单,大家其实只要明白了这个通信原理,结合自己框架代码,接口验证来完成自己的登录通信