【ASP NET】UCenter實現多站點同步登入退出

SunnyD發表於2017-12-14

利用UCenter實現discuz論壇和應用網站同步登入和退出功能 測試環境:Discuz! X3.2UCenter 1.6.Net Framework 4.0

進入Discuz 後臺的UCenter應用管理頁面

UCenter

新增新應用

安裝方式選擇自定義安裝、應用型別為其他。通訊金鑰可以自定義。開啟同步登入和通知

新增新應用

整合UCenter API For DotNet

UC配置資訊

DS.Web.UCenter新增到專案中 修改專案App.Config配置資訊: UC_KEY 新增新應用時填寫的通訊金鑰 UC_API UCenter地址 UC_APPID 應用網站在UCenter中的id

配置完畢後將網站執行起來,重新整理一下應用列表介面

通訊成功

如果上述配置資訊正確,就可以看到應用通訊成功了。

呼叫UCenter API

以登入為例,例項化一個UcClient物件,呼叫UserLogin方法

IUcClient client = new UcClient();
var user = client.UserLogin("admin", "admin"); //登陸
if (user.Success) //判斷是否登陸成功
{
    client.PmSend(0, 0, "公告", "測試公告", user.Uid); //給該使用者傳送系統訊息
}
複製程式碼

其他相關的API

using System.Collections.Generic;

namespace DS.Web.UCenter.Client
{
    ///<summary>
    /// UcApi客戶端
    ///</summary>
    public interface IUcClient
    {
        /// <summary>
        /// 使用者註冊
        /// </summary>
        /// <param name="userName">使用者名稱</param>
        /// <param name="passWord">密碼</param>
        /// <param name="email">Email</param>
        /// <param name="questionId">登陸問題</param>
        /// <param name="answer">答案</param>
        /// <returns></returns>
        UcUserRegister UserRegister(string userName, string passWord, string email, int questionId = 0, string answer = "");

        /// <summary>
        /// 使用者登陸
        /// </summary>
        /// <param name="userName">使用者名稱/Uid/Email</param>
        /// <param name="passWord">密碼</param>
        /// <param name="loginMethod">登入方式</param>
        /// <param name="checkques">需要登陸問題</param>
        /// <param name="questionId">問題ID</param>
        /// <param name="answer">答案</param>
        /// <returns></returns>
        UcUserLogin UserLogin(string userName, string passWord, LoginMethod loginMethod = LoginMethod.UserName, bool checkques = false, int questionId = 0, string answer = "");

        /// <summary>
        /// 得到使用者資訊
        /// </summary>
        /// <param name="userName">使用者名稱</param>
        /// <returns></returns>
        UcUserInfo UserInfo(string userName);

        /// <summary>
        /// 得到使用者資訊
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns></returns>
        UcUserInfo UserInfo(int uid);

        /// <summary>
        /// 更新使用者資訊
        /// 更新資料需驗證使用者的原密碼是否正確,除非指定 ignoreoldpw 為 1。
        /// 如果只修改 Email 不修改密碼,可讓 newpw 為空;
        /// 同理如果只修改密碼不修改 Email,可讓 email 為空。
        /// </summary>
        /// <returns></returns>
        UcUserEdit UserEdit(string userName, string oldPw, string newPw, string email, bool ignoreOldPw = false, int questionId = 0, string answer = "");

        /// <summary>
        /// 刪除使用者
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns></returns>
        bool UserDelete(params int[] uid);

        /// <summary>
        /// 刪除使用者頭像
        /// </summary>
        /// <param name="uid">Uid</param>
        void UserDeleteAvatar(params int[] uid);

        /// <summary>
        /// 同步登陸
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns>同步登陸的 Html 程式碼</returns>
        string UserSynlogin(int uid);

        /// <summary>
        /// 同步登出
        /// </summary>
        /// <returns>同步登出的 Html 程式碼</returns>
        string UserSynLogout();

        /// <summary>
        /// 檢查 Email 格式
        /// </summary>
        /// <param name="email">Email</param>
        /// <returns></returns>
        UcUserCheckEmail UserCheckEmail(string email);

        /// <summary>
        /// 增加受保護使用者
        /// </summary>
        /// <param name="admin">操作管理員</param>
        /// <param name="userName">使用者名稱</param>
        /// <returns></returns>
        bool UserAddProtected(string admin, params string[] userName);

        /// <summary>
        /// 刪除受保護使用者
        /// </summary>
        /// <param name="admin">操作管理員</param>
        /// <param name="userName">使用者名稱</param>
        /// <returns></returns>
        bool UserDeleteProtected(string admin, params string[] userName);

        /// <summary>
        /// 得到受保護使用者
        /// </summary>
        /// <returns></returns>
        UcUserProtecteds UserGetProtected();

        /// <summary>
        /// 合併使用者
        /// </summary>
        /// <param name="oldUserName">老使用者名稱</param>
        /// <param name="newUserName">新使用者名稱</param>
        /// <param name="uid">Uid</param>
        /// <param name="passWord">密碼</param>
        /// <param name="email">Email</param>
        /// <returns></returns>
        UcUserMerge UserMerge(string oldUserName, string newUserName, int uid, string passWord, string email);

        /// <summary>
        /// 移除重名使用者記錄
        /// </summary>
        /// <param name="userName">使用者名稱</param>
        void UserMergeRemove(string userName);

        /// <summary>
        /// 得到使用者積分
        /// </summary>
        /// <param name="appId">應用程式Id</param>
        /// <param name="uid">Uid</param>
        /// <param name="credit">積分編號</param>
        /// <returns></returns>
        int UserGetCredit(int appId, int uid, int credit);

        /// <summary>
        /// 檢查新訊息
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns></returns>
        UcPmCheckNew PmCheckNew(int uid);

        /// <summary>
        /// 傳送短訊息
        /// </summary>
        /// <param name="fromUid">發件人使用者 ID,0 為系統訊息</param>
        /// <param name="replyPmId">回覆的訊息 ID,0:傳送新的短訊息,大於 0:回覆指定的短訊息</param>
        /// <param name="subject">訊息標題</param>
        /// <param name="message">訊息內容</param>
        /// <param name="msgTo">收件人ID</param>
        /// <returns></returns>
        UcPmSend PmSend(int fromUid, int replyPmId, string subject, string message, params int[] msgTo);

        /// <summary>
        /// 傳送短訊息
        /// </summary>
        /// <param name="fromUid">發件人使用者 ID,0 為系統訊息</param>
        /// <param name="replyPmId">回覆的訊息 ID,0:傳送新的短訊息,大於 0:回覆指定的短訊息</param>
        /// <param name="subject">訊息標題</param>
        /// <param name="message">訊息內容</param>
        /// <param name="msgTo">收件人使用者名稱</param>
        /// <returns></returns>
        UcPmSend PmSend(int fromUid, int replyPmId, string subject, string message, params string[] msgTo);

        /// <summary>
        /// 刪除短訊息
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="folder">資料夾</param>
        /// <param name="pmIds">短訊息ID</param>
        /// <returns>刪除的數量</returns>
        int PmDelete(int uid, PmDeleteFolder folder, params int[] pmIds);

        /// <summary>
        /// 刪除會話
        /// </summary>
        /// <param name="uid">發件人</param>
        /// <param name="toUids">收件人</param>
        /// <returns>刪除的數量</returns>
        int PmDelete(int uid, params int[] toUids);

        /// <summary>
        /// 修改閱讀狀態
        /// </summary>
        /// <param name="uid">發件人</param>
        /// <param name="toUids">收件人</param>
        /// <param name="pmIds">短訊息ID</param>
        /// <param name="readStatus">閱讀狀態</param>
        void PmReadStatus(int uid, int toUids, int pmIds = 0, ReadStatus readStatus = ReadStatus.Readed);

        /// <summary>
        /// 修改閱讀狀態
        /// </summary>
        /// <param name="uid">發件人</param>
        /// <param name="toUids">收件人陣列</param>
        /// <param name="pmIds">短訊息ID陣列</param>
        /// <param name="readStatus">閱讀狀態</param>
        void PmReadStatus(int uid, IEnumerable<int> toUids, IEnumerable<int> pmIds, ReadStatus readStatus = ReadStatus.Readed);

        /// <summary>
        /// 獲取短訊息列表
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="page">當前頁編號,預設值 1</param>
        /// <param name="pageSize">每頁最大條目數,預設值 10</param>
        /// <param name="folder">短訊息所在的資料夾</param>
        /// <param name="filter">過濾方式</param>
        /// <param name="msgLen">擷取短訊息內容文字的長度,0 為不擷取,預設值 0</param>
        /// <returns></returns>
        UcPmList PmList(int uid, int page = 1, int pageSize = 10, PmReadFolder folder = PmReadFolder.NewBox, PmReadFilter filter = PmReadFilter.NewPm, int msgLen = 0);

        /// <summary>
        /// 獲取短訊息內容
        /// 本介面函式用於返回指定使用者的指定訊息 ID 的訊息,返回的資料中包含針對這個訊息的回覆。
        /// 如果指定 touid 引數,那麼短訊息將列出所有 uid 和 touid 之間的短訊息,daterange 可以指定返回訊息的日期範圍。
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="pmId">短訊息ID</param>
        /// <param name="toUid">收件人ID</param>
        /// <param name="dateRange">日期範圍</param>
        /// <returns></returns>
        UcPmView PmView(int uid, int pmId, int toUid = 0, DateRange dateRange = DateRange.Today);

        /// <summary>
        /// 獲取單條短訊息內容
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="type">型別</param>
        /// <param name="pmId">短訊息ID</param>
        /// <returns></returns>
        UcPm PmViewNode(int uid, ViewType type = ViewType.Specified, int pmId = 0);

        /// <summary>
        /// 忽略未讀訊息提示
        /// </summary>
        /// <param name="uid">Uid</param>
        void PmIgnore(int uid);

        /// <summary>
        /// 得到黑名單
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns></returns>
        UcPmBlacklsGet PmBlacklsGet(int uid);

        /// <summary>
        /// 設定黑名單為禁止所有人(清空原資料)
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns></returns>
        bool PmBlacklsSetAll(int uid);

        /// <summary>
        /// 設定黑名單(清空原資料)
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="userName">黑名單使用者名稱</param>
        /// <returns></returns>
        bool PmBlacklsSet(int uid, params string[] userName);

        /// <summary>
        /// 新增黑名單為禁止所有人
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns></returns>
        bool PmBlacklsAddAll(int uid);

        /// <summary>
        /// 增加黑名單
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="userName">黑名單使用者名稱</param>
        /// <returns></returns>
        bool PmBlacklsAdd(int uid, params string[] userName);

        /// <summary>
        /// 刪除黑名單中的禁止所有人
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <returns></returns>
        void PmBlacklsDeleteAll(int uid);

        /// <summary>
        /// 刪除黑名單
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="userName">黑名單使用者名稱</param>
        void PmBlacklsDelete(int uid, params string[] userName);

        /// <summary>
        /// 增加好友
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="friendId">好友ID</param>
        /// <param name="comment">備註</param>
        /// <returns></returns>
        bool UcFriendAdd(int uid, int friendId, string comment = "");

        /// <summary>
        /// 刪除好友
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="friendIds">好友ID</param>
        /// <returns></returns>
        bool UcFriendDelete(int uid, params int[] friendIds);

        /// <summary>
        /// 獲取好友總數
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="direction">方向</param>
        /// <returns>好友數目</returns>
        int UcFriendTotalNum(int uid, FriendDirection direction = FriendDirection.All);

        /// <summary>
        /// 好友列表
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="page">當前頁編號</param>
        /// <param name="pageSize">每頁最大條目數</param>
        /// <param name="totalNum">好友總數</param>
        /// <param name="direction">方向</param>
        /// <returns></returns>
        UcFriends UcFriendList(int uid, int page = 1, int pageSize = 10, int totalNum = 10, FriendDirection direction = FriendDirection.All);

        /// <summary>
        /// 積分兌換請求
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="from">原積分</param>
        /// <param name="to">目標積分</param>
        /// <param name="toAppId">目標應用ID</param>
        /// <param name="amount">積分數額</param>
        /// <returns></returns>
        bool UcCreditExchangeRequest(int uid, int from, int to, int toAppId, int amount);

        ///<summary>
        /// 修改頭像
        ///</summary>
        ///<param name="uid">Uid</param>
        ///<param name="type"></param>
        ///<returns></returns>
        string Avatar(int uid, AvatarType type = AvatarType.Virtual);

        /// <summary>
        /// 得到頭像地址
        /// </summary>
        /// <param name="uid">Uid</param>
        /// <param name="size">大小</param>
        /// <param name="type">型別</param>
        /// <returns></returns>
        string AvatarUrl(int uid,AvatarSize size,AvatarType type = AvatarType.Virtual);

        /// <summary>
        /// 檢查頭像是否存在
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="size"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        bool AvatarCheck(int uid, AvatarSize size = AvatarSize.Middle, AvatarType type = AvatarType.Virtual);

        /// <summary>
        /// 獲取標籤資料
        /// </summary>
        /// <param name="tagName">標籤名</param>
        /// <param name="number">應用程式ID對應的數量</param>
        /// <returns></returns>
        UcTags TagGet(string tagName, IEnumerable<KeyValuePair<string, string>> number);

        /// <summary>
        /// 新增事件
        /// </summary>
        /// <param name="icon">圖示型別,如:thread、post、video、goods、reward、debate、blog、album、comment、wall、friend</param>
        /// <param name="uid">Uid</param>
        /// <param name="userName">使用者名稱</param>
        /// <param name="titleTemplate">標題模板</param>
        /// <param name="titleData">標題資料陣列</param>
        /// <param name="bodyTemplate">內容模板</param>
        /// <param name="bodyData">模板資料</param>
        /// <param name="bodyGeneral">相同事件合併時用到的資料:特定的陣列,只有兩項:name、link,保留</param>
        /// <param name="targetIds">保留</param>
        /// <param name="images">相關圖片的 URL 和連結地址。一個圖片地址,一個連結地址</param>
        /// <returns></returns>
        int FeedAdd(FeedIcon icon, int uid, string userName, string titleTemplate, string titleData, string bodyTemplate, string bodyData, string bodyGeneral, string targetIds, params string[] images);

        /// <summary>
        /// 得到Feed
        /// </summary>
        /// <param name="limit">數量限制</param>
        /// <returns></returns>
        UcFeeds FeedGet(int limit);

        /// <summary>
        /// 得到應用列表
        /// </summary>
        /// <returns></returns>
        UcApps AppList();

        /// <summary>
        /// 新增郵件到佇列
        /// </summary>
        /// <param name="subject">標題</param>
        /// <param name="message">內容</param>
        /// <param name="uids">Uid</param>
        /// <returns></returns>
        UcMailQueue MailQueue(string subject, string message,params int[] uids);

        /// <summary>
        /// 新增郵件到佇列
        /// </summary>
        /// <param name="subject">標題</param>
        /// <param name="message">內容</param>
        /// <param name="emails">目標Email</param>
        /// <returns></returns>
        UcMailQueue MailQueue(string subject, string message, params string[] emails);

        /// <summary>
        /// 新增郵件到佇列
        /// </summary>
        /// <param name="subject">標題</param>
        /// <param name="message">內容</param>
        /// <param name="uids">Uid</param>
        /// <param name="emails">目標email</param>
        /// <returns></returns>
        UcMailQueue MailQueue(string subject, string message, int[] uids, string[] emails);

        /// <summary>
        /// 新增郵件到佇列
        /// </summary>
        /// <param name="subject">標題</param>
        /// <param name="message">內容</param>
        /// <param name="fromMail">發信人,可選引數,預設為空,uc後臺設定的郵件來源作為發信人地址</param>
        /// <param name="charset">郵件字符集,可選引數,預設為gbk</param>
        /// <param name="htmlOn">是否是html格式的郵件,可選引數,預設為FALSE,即文字郵件</param>
        /// <param name="level">郵件級別,可選引數,預設為1,數字大的優先傳送,取值為0的時候立即傳送,郵件不入佇列</param>
        /// <param name="uids">Uid</param>
        /// <param name="emails">目標email</param>
        /// <returns></returns>
        UcMailQueue MailQueue(string subject,string message,string fromMail,string charset,bool htmlOn,int level,int[] uids,string[] emails);
    }
}
複製程式碼

供UCenter呼叫的介面

在站點新建一個路徑為/API/uc.ashx的檔案 (資料夾名稱要大寫) 新增以下程式碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DS.Web.UCenter.Api;

namespace DS.Web.UCenter.Website.API
{
    /// <summary>
    /// Summary description for uc
    /// </summary>
    public class uc:UcApiBase
    {
        // 使用者被刪除
        public override ApiReturn DeleteUser(IEnumerable<int> ids)
        {
            throw new NotImplementedException();
        }

        // 修改了使用者名稱
        public override ApiReturn RenameUser(int uid, string oldUserName, string newUserName)
        {
            throw new NotImplementedException();
        }

        public override UcTagReturns GetTag(string tagName)
        {
            throw new NotImplementedException();
        }

        // 同步登入
        public override ApiReturn SynLogin(int uid)
        {
            throw new NotImplementedException();
        }

        // 同步退出
        public override ApiReturn SynLogout()
        {
            throw new NotImplementedException();
        }

        // 密碼更新
        public override ApiReturn UpdatePw(string userName, string passWord)
        {
            throw new NotImplementedException();
        }

        public override ApiReturn UpdateBadWords(UcBadWords badWords)
        {
            throw new NotImplementedException();
        }

        public override ApiReturn UpdateHosts(UcHosts hosts)
        {
            throw new NotImplementedException();
        }

        public override ApiReturn UpdateApps(UcApps apps)
        {
            throw new NotImplementedException();
        }

        public override ApiReturn UpdateClient(UcClientSetting client)
        {
            throw new NotImplementedException();
        }

        public override ApiReturn UpdateCredit(int uid, int credit, int amount)
        {
            throw new NotImplementedException();
        }

        public override UcCreditSettingReturns GetCreditSettings()
        {
            throw new NotImplementedException();
        }

        public override ApiReturn GetCredit(int uid, int credit)
        {
            throw new NotImplementedException();
        }

        public override ApiReturn UpdateCreditSettings(UcCreditSettings creditSettings)
        {
            throw new NotImplementedException();
        }
    }
}
複製程式碼

這些是提供給UCenter呼叫的介面,例如當使用者在discuz登入時,UCenter會傳送一個通知(請求uc.ashx),把登入的使用者uid等資訊傳遞過來,我們要做的就是在自己的SynLogin中寫登入的cookie或session等操作。 同時,在SynLogout中加上清除cookie和session的處理。就實現了同步登入和退出功能。

注意點

  • 新增應用時一定要勾選 開啟同步登入接受通知
  • 需要正確填寫UC各項必填的配置資訊
  • 確保在bbs站點存在/uc_client/data/cache/apps.php檔案,沒有的話從/uc_server/data/cache/apps.php拷貝一份
  • 要將上述配置資訊放到站點的Web.config

同步註冊

如果你的網站還需要同步註冊功能,請參考[【ASP.Net】UCenter實現多站點同步登入退出】(http://www.jianshu.com/p/1caa425ef24b)

相關文章