問題描述
上一篇文章寫了【ASP.Net】UCenter實現多站點同步登錄退出
在整合論壇的時候,同步注冊也是相當必要的一個功能:將論壇注冊的用戶同步到自己的網站,自己網站注冊的用戶同步到論壇。
官方提供的API里并沒有這個功能,我們只能自己實現。
問題分析
根據UCenter同步登錄的原理:
- 在某個網站登錄成功后,向UCenter發出一個同步登錄通知
- UCenter接收到通知后獲取所有app列表,生成一段請求所有開啟同步登錄app的uc接口傳遞
action=synlogin&time=xxx&uid=xxx
等信息的<script></script>
字符串- 該網站拿到這一段js后輸出到頁面,頁面就會請求這些app的uc接口
- app接收到同步登錄的通知,在網站寫登錄的cookie/session實現同步登錄
接下來,就看看同步登錄的具體邏輯
同步登錄分析
在Discuz! X3.2的class.member.php
文件約139行和276行,有這么一段代碼
意思是判斷是否開啟了同步登錄,是則調用uc_user_synlogin
獲取同步登錄的js并輸出到頁面
那我們再來看一下uc_user_synlogin
函數,在/uc_client/client.php
文件第365行
調用了一個uc_api_post
函數,找一下這個函數,就在當前文件中
原來是請求了/uc_server/index.php
,并傳遞m=user&a=synlogin
那我們就再看一下/uc_server/index.php
文件
把剛剛的傳遞的m拼上control,a前面拼上on,即創建了一個usercontrol
對象,調用了onsynlogin
方法
而這個usercontrol
類就在/uc_server/control/user.php
文件中,看31行
終于找到了這個同步登錄的真面目!里面干的事情就是上面所說的,獲取全部開啟了同步登錄的app,然后發出同步登錄通知(請求uc接口,傳遞action=synlogin&username=xxx
等參數,通知各個app處理登錄)
處理同步注冊
先從底層開始,依葫蘆畫瓢。還是在/uc_server/control/user.php
文件中,onsynlogin
方法的下面
復制一下上面的onsynlogin
方法,把注冊必填的username
password
email
參數替換進去,改造成我們需要的onsynregister
函數。
接下來,倒回到/uc_client/client.php
文件第365行,uc_user_synlogin
方法這里,同樣復制一下,改造成一個uc_user_synregister
方法
最后一步,在/source/class/class_member.php
,第923行,論壇注冊的地方,加上我們同步注冊的代碼
到這里,論壇每次有新用戶注冊之后,UCenter就會向所有應用的站點發出同步請求,這時只需要在應用站點的/API/uc.ashx文件中增加一個注冊本站用戶的接口功能即可實現站點與論壇同步注冊的功能。
改造DS.Web.UCenter
- 在
UcActions.cs
文件里面添加一個SynRegister
屬性
/// <summary>
/// 同步注冊
/// </summary>
public static string SynRegister { get { return "synregister"; } }
- 在
UcApiBase.cs
文件添加同步注冊的處理,就加在登錄的后面
首先是抽象方法聲明
/// <summary>
/// 同步登陸
/// </summary>
/// <param name="uid">uid</param>
/// <returns></returns>
public abstract ApiReturn SynLogin(int uid);
/// <summary>
/// 同步注冊
/// </summary>
/// <param name="username">用戶名</param>
/// <param name="password">密碼</param>
/// <param name="email">郵箱</param>
/// <returns></returns>
public abstract ApiReturn SynRegister(string username, string password, string email);
還有action處理
else if (Args.Action == UcActions.SynLogin)
{
synLogin();
}
// 同步注冊
else if (Args.Action == UcActions.SynRegister)
{
synRegister();
}
調用同步注冊的地方
private void synLogin()
{
if (!UcConfig.ApiSynLogin) writeForbidden();
Response.Headers.Add("P3P", "CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");
int uid;
int.TryParse(Args.QueryString["uid"], out uid);
writeEnd(SynLogin(uid));
}
// 同步注冊
private void synRegister()
{
string username = Args.QueryString["username"];
string password = Args.QueryString["password"];
string email = Args.QueryString["email"];
writeEnd(SynRegister(username, password, email));
}
- 最后在
/API/uc.ashx
接口中加上自己網站同步注冊的邏輯(將用戶數據插入數據庫等等)
public override ApiReturn SynRegister(string username, string password, string email)
{
return ApiReturn.Success;
}
OK!大功告成