問題描述
上一篇文章寫了【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!大功告成