随笔 - 934, 文章 - 0, 评论 - 249, 阅读 - 345万

导航

< 2025年3月 >
23 24 25 26 27 28 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 27 28 29
30 31 1 2 3 4 5

Discuz x3 UCenter实现同步登陆原理

Posted on   蝈蝈俊  阅读(2793)  评论(0编辑  收藏  举报

1、Discuz x3 的登录页面URL是:/member.php?mod=logging&action=login

2、这个登录页面,登录提交的地址是:
<form method="post" autocomplete="off" name="login" id="loginform_LKsWY" class="cl" onsubmit="pwdclear = 1;ajaxpost('loginform_LKsWY', 'returnmessage_LKsWY', 'returnmessage_LKsWY', 'onerror');return false;" action="member.php?mod=logging&amp;action=login&amp;loginsubmit=yes&amp;handlekey=login&amp;loginhash=LKsWY" fwin="login">

在 /member.php 文件中,我们可以看到对应的加载的mod文件:
require DISCUZ_ROOT.'./source/module/member/member_'.$mod.'.php';

在/source/module/member/member_logging 文件中,我们看到下面代码:
ctlobj=newloggingctl();ctl_obj->setting = G[setting];method = 'on_'.GET[action];ctl_obj->template = 'member/login';
ctlobj>method();

这里的类 logging_ctl 来自 source/class/class_member.php 文件。
这个类的 function on_login() 方法就是登录处理的方法。

其中 on_login() 方法中下面这一行就是判断DB中数据是否能匹配。也就是对username和password进行验证。
     result=userlogin(_GET['username'], GET[password],_GET['questionid'], GET[answer],this->setting['autoidselect'] ? 'auto' : GET[loginfield],_G['clientip']);
这个函数的实现在 source/function/function_member.php 这个文件中。

 

3、如果验证成功,将调用位于uc_client下client.php文件中的函数uc_user_synlogin,
class_member.php中调用代码:
    ucsynlogin=this->setting['allowsynlogin'] ? uc_user_synlogin($_G['uid']) : '';

uc_client下client.php文件中,uc_user_synlogin(uid)return = uc_api_post('user', 'synlogin', array('uid'=>$uid));

参考:http://bbs.phpchina.com/thread-112304-1-1.html

uc_api_post函数的作用是将将数据通过socket发送到ucenter。

对应的代码在 client.php 文件中,代码如下:

function uc_api_post(module,action, $arg = array()) {
    s=sep = '';
    foreach(argask => v) {             $k = urlencode($k);             if(is_array($v)) {                 $s2 = $sep2 = '';                 foreach($v as $k2 => $v2) {                     $k2 = urlencode($k2);                     $s2 .= "$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2));                     $sep2 = '&';                 }                 $s .= $sep.$s2;             } else {                 $s .= "$sep$k=".urlencode(uc_stripslashes($v));             }             $sep = '&';         }postdata = uc_api_requestdata(module,action, s);returnucfopen2(UCAPI./index.php,500000,postdata, '', TRUE, UC_IP, 20);
}

注意是向:UC_API.'/index.php' 这个地址, 一般是 /uc_server/index.php 这个文件。

4、然后这个函数后向Ucenter的index.php传递数据,index.php接受传递的数据,获得model为user,action为synlogin的值。

5、然后Ucenter的index.php调用/uc_server/control目录下的user.php类中的onsynlogin方法,

/uc_server/index.php  代码中如下代码:

define('UC_ROOT', dirname(__FILE__).'/');
include UC_ROOT."control/m.php";method = 'on'.$a;

通过foreach循环,以javascript的方式通知uc应用列表中开启同步登陆的应用进行同步登录;即通过get方式传递给各个应用目录中api下的uc.php一些数据。

6、uc.php接收通知并处理get过来的数据,并在函数synlogin(位于uc.php中)通过函数_authcode加密数据(默认以UC_KEY作为密钥),用函数_setcookie设置cookie。

7、各个应用用对应的密钥解码上面设置的cookie,得到用户id等数据;通过这个值来判断用户是否经过其它应用登录过,从而让用户可以自动登陆。

应用程序的logging.php ------>uc_client中的client.php------>Ucenter------>应用程序中api/uc.php

其实Ucenter实现同步登陆的原理就是cookie,一个应用登陆成功之后,向Ucenter传递数据,让Ucenter通知其他的应用也设置cookie,这样用户在访问其他应用的时候通过已经设置好的cookie实现自动登陆。了解了Ucenter的同步原理,再遇到无法同步登陆,或者开发一些与UCenter接口的时候就会容易很多。

 

 

参考资料:

ucenter单点登陆总结
http://xuebingnanmm.iteye.com/blog/681695

个人对UCenter通信原理的总结
http://bbs.phpchina.com/thread-112304-1-1.html

无需激活直接同步登入discuz,php代码(直接可用)
http://www.discuz.net/thread-3495435-1-1.html

UCenter实现同步登陆原理
http://xuqin.blog.51cto.com/5183168/1293551

[已解决] 修改文件实现Discuz新注册帐号同步其他应用
http://www.discuz.net/forum.php?mod=viewthread&tid=3522745

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
历史上的今天:
2013-04-03 Go语言Revel框架 的聊天室示例解读
点击右上角即可分享
微信分享提示