Discuz!nt整合心得

最近研究了下Discuz!nt的整合,由於是網上找的實例,有個地方的寫錯了,致使糾結了一成天,這裏分享出來.ajax

Discuz!nt提供了整合工具DiscuzToolkit,用於調用Discuz!nt API的一款工具,網上可以很輕鬆的找到源碼,可是項目中須要引用幾個DLL,如圖數據庫

這裏附上代碼api

 1  //登陸 
 2         protected void btnLogin_Click(object sender, EventArgs e)
 3         {
 4             string username = un.Value.Trim();
 5             string password = pwd.Value.Trim();
 6 
 7             string apikey = "3b8ccea63030e2747abf5740b2f57350";//有Discuz後臺管理擴展->通行證設置得到
 8             string secret = "7d0a34cfa6f7e2175e03aead1c52fe4c";//同上
 9             string url = "http://bbs.oyytv.com/";//你的bbs路徑
10             string cookieDomain = "oyytv.com";//你的域名
11             DiscuzSession ds = new DiscuzSession(apikey, secret, url);
12             int id = ds.GetUserID(username);//根據用戶名獲取用戶ID
13             //用戶名存在
14             if (id > 0)
15             {
16                 //取得用戶數據庫中的密碼
17                 string dbpassword = ds.GetUserInfo(id).Password;
18                 //判斷數據庫中的密碼和輸入的密碼是否一致
19                 if (dbpassword == FormsAuthentication.HashPasswordForStoringInConfigFile(password, "MD5").ToLower())
20                 {
21                     //輸入密碼正確,則登陸
22                     ds.Login(id, dbpassword, true, 10000, cookieDomain);
23 
24                     Discuz.Config.GeneralConfigInfo config = Discuz.Config.GeneralConfigs.GetConfig();
25 
26                     //刪除以前的錯誤登陸信息
27                     LoginLogs.DeleteLoginLog(DNTRequest.GetIP());
28                     //根據積分公式刷新用戶總積分
29                     UserCredits.UpdateUserCredits(id);
30                     //寫入用戶登陸後的cookie
31                     ForumUtils.WriteUserCookie(id, Utils.StrToInt(DNTRequest.GetString("expires"), -1), config.Passwordkey, DNTRequest.GetInt("templateid", 0), DNTRequest.GetInt("loginmode", -1));
32 
33                     Response.Redirect("http://bbs.oyytv.com");
34                     //更新用戶最後動做,如不須要可不執行
35                     //OnlineUsers.UpdateAction(olid, UserAction.Login.ActionID, 0, config.Onlinetimeout);
36                     //更新該用戶最後訪問時間
37                     // Users.UpdateUserLastvisit(id, DNTRequest.GetIP());
38                 }
39                 else
40                 {
41 
42                 }
43             }
44             else
45             {
46 
47             }
48 
49         }

 

這裏有幾個存在誤解的地方跨域

整合,由於Discuz!nt是用cookie來保存用戶狀態,經過設置cookie的Domain來進行子站間的跨域,這裏整合說的統一登陸,註冊...,只是針對於子站間的跨域,就是說將一個論壇,包含在你現有系統上緩存

代碼第10行,設置的其實就是Domain值.cookie

第22行 ds.Login(id, dbpassword, true, 10000, cookieDomain);併發

 1 /// <summary>
 2         /// 登陸
 3         /// </summary>
 4         /// <param name="uid"></param>
 5         /// <param name="password"></param>
 6         /// <param name="isMD5Passwd"></param>
 7         /// <param name="expires"></param>
 8         /// <param name="cookieDomain"></param>
 9         public void Login(int uid, string password, bool isMD5Passwd, int expires, string cookieDomain)
10         {
11             User user = GetUserInfo(uid);
12             HttpCookie cookie = new HttpCookie("dnt");
13             cookie.Values["userid"] = user.UId.ToString();
14             cookie.Values["password"] = EncodePassword(password, isMD5Passwd);
15             cookie.Values["avatar"] = HttpUtility.UrlEncode(user.Avatar.ToString());
16             cookie.Values["tpp"] = user.Tpp.ToString();
17             cookie.Values["ppp"] = user.Ppp.ToString();
18             cookie.Values["invisible"] = user.Invisible.ToString();
19             cookie.Values["referer"] = "index.aspx";
20             cookie.Values["expires"] = expires.ToString();
21             if (expires > 0)
22             {
23                 cookie.Expires = DateTime.Now.AddMinutes(expires);
24             }
25             cookie.Domain = cookieDomain;
26             cookie.Path = "/";
27             HttpContext.Current.Response.AppendCookie(cookie);
28         }

這裏的登陸只是存一個子站間能夠互相訪問的cookie而已,要注意的是22行的密碼,應該保存加密後的密碼而不是明文密碼,不然會致使你存的cookie在discuz!nt驗證失敗.ide

這裏我說說discuz!nt的驗證方式,全部頁面都繼承於PageBase,在它的構造函數裏面會獲取用戶信息,來判斷用戶是不是遊客,仍是普通用戶,這裏的判斷標識是以userid來判斷,-1表示遊客函數

 1  public PageBase()
 2         {
 3             if (recordPageView)
 4                 PageViewStatistic(pagename);
 5 
 6             config = GeneralConfigs.GetConfig();
 7             if (SpacePluginProvider.GetInstance() == null)
 8                 config.Enablespace = 0;
 9             if (AlbumPluginProvider.GetInstance() == null)
10                 config.Enablealbum = 0;
11             if (MallPluginProvider.GetInstance() == null)
12                 config.Enablemall = 0;
13 
14             LoadUrlConfig();
15             userid = Utils.StrToInt(ForumUtils.GetCookie("userid"), -1);
16             //清空當前頁面查詢統計
17 #if DEBUG
18             Discuz.Data.DbHelper.QueryCount = 0;
19             Discuz.Data.DbHelper.QueryDetail = "";
20 #endif
21             // 若是啓用遊客頁面緩存,則對遊客輸出緩存頁
22             if (userid == -1 && config.Guestcachepagetimeout > 0 && GetUserCachePage(pagename))
23                 return;
24 
25             AddMetaInfo(config.Seokeywords, config.Seodescription, config.Seohead);
26 
27             if (config.Nocacheheaders == 1)
28             {
29                 System.Web.HttpContext.Current.Response.BufferOutput = false;
30                 System.Web.HttpContext.Current.Response.ExpiresAbsolute = DateTime.Now.AddDays(-1);
31                 System.Web.HttpContext.Current.Response.Cache.SetExpires(DateTime.Now.AddDays(-1));
32                 System.Web.HttpContext.Current.Response.Expires = 0;
33                 System.Web.HttpContext.Current.Response.CacheControl = "no-cache";
34                 System.Web.HttpContext.Current.Response.Cache.SetNoStore();
35             }
36 
37             //當爲forumlist.aspx或forumindex.aspx,可能出如今線併發問題,這時系統會延時2秒
38             if ((pagename != "forumlist.aspx") && (pagename != "forumindex.aspx"))
39                 oluserinfo = OnlineUsers.UpdateInfo(config.Passwordkey, config.Onlinetimeout);
40             else
41             {
42                 try
43                 {
44                     oluserinfo = OnlineUsers.UpdateInfo(config.Passwordkey, config.Onlinetimeout);
45                 }
46                 catch
47                 {
48                     System.Threading.Thread.Sleep(2000);
49                     oluserinfo = OnlineUsers.UpdateInfo(config.Passwordkey, config.Onlinetimeout);
50                 }
51             }

代碼15行,先獲取用戶id,這裏是從cookie裏面獲取的,而後再根據id,pwd獲取用戶信息(代碼44行).工具

這裏咱們看看UpdateInfo函數,代碼以下:

1 /// <summary>
2         /// 用戶在線信息維護。判斷當前用戶的身份(會員仍是遊客),是否在在線列表中存在,若是存在則更新會員的當前動,不存在則創建.
3         /// </summary>
4         /// <param name="passwordkey">用戶密碼</param
5         /// <param name="timeout">在線超時時間</param>
6         public static OnlineUserInfo UpdateInfo(string passwordkey, int timeout)
7         {
8             return UpdateInfo(passwordkey, timeout, -1, "");
9         }

在這裏,它又重載了一次,重載代碼以下:

 1         /// <summary>
 2         /// 用戶在線信息維護。判斷當前用戶的身份(會員仍是遊客),是否在在線列表中存在,若是存在則更新會員的當前動,不存在則創建.
 3         /// </summary>
 4         /// <param name="passwordkey">論壇passwordkey</param>
 5         /// <param name="timeout">在線超時時間</param>
 6         /// <param name="passwd">用戶密碼</param>
 7         public static OnlineUserInfo UpdateInfo(string passwordkey, int timeout, int uid, string passwd)
 8         {
 9             lock (SynObject)
10             {
11                 OnlineUserInfo onlineuser = new OnlineUserInfo();
12                 string ip = DNTRequest.GetIP();
13                 int userid = TypeConverter.StrToInt(ForumUtils.GetCookie("userid"), uid);
14                 string password = (Utils.StrIsNullOrEmpty(passwd) ? ForumUtils.GetCookiePassword(passwordkey) : ForumUtils.GetCookiePassword(passwd, passwordkey));
15 
16                 // 若是密碼非Base64編碼字符串則懷疑被非法篡改, 直接置身份爲遊客
17                 if (password.Length == 0 || !Utils.IsBase64String(password))
18                     userid = -1;
19 
20                 if (userid != -1)
21                 {
22                     onlineuser = GetOnlineUser(userid, password);
23 
24                     //更新流量統計
25                     if (!DNTRequest.GetPageName().EndsWith("ajax.aspx") && GeneralConfigs.GetConfig().Statstatus == 1)
26                         Stats.UpdateStatCount(false, onlineuser != null);
27 
28                     if (onlineuser != null)
29                     {
30                         if (onlineuser.Ip != ip)
31                         {
32                             UpdateIP(onlineuser.Olid, ip);
33                             onlineuser.Ip = ip;
34                             return onlineuser;
35                         }
36                     }
37                     else
38                     {
39                         // 判斷密碼是否正確
40                         userid = Users.CheckPassword(userid, password, false);
41                         if (userid != -1)
42                         {
43                             Discuz.Data.OnlineUsers.DeleteRowsByIP(ip);
44                             CheckIp(ip);
45                             return CreateUser(userid, timeout);
46                         }
47                         else
48                         {
49                             CheckIp(ip);
50                             // 如密碼錯誤則在在線表中建立遊客
51                             onlineuser = GetOnlineUserByIP(-1, ip);
52                             if (onlineuser == null)
53                                 return CreateGuestUser(timeout);
54                         }
55                     }
56                 }
57                 else
58                 {
59                     onlineuser = GetOnlineUserByIP(-1, ip);
60                     //更新流量統計
61                     if (!DNTRequest.GetPageName().EndsWith("ajax.aspx") && GeneralConfigs.GetConfig().Statstatus == 1)
62                         Stats.UpdateStatCount(true, onlineuser != null);
63 
64                     if (onlineuser == null)
65                         return CreateGuestUser(timeout);
66                 }
67 
68                 //onlineuser.Lastupdatetime = Utils.GetDateTime();  爲了客戶端可以登陸註釋此句,若有問題再修改。
69                 return onlineuser;
70             }
71         }

在這塊,會產生極大的誤解,由於前文已經說過,-1是判斷是遊客的userid,然而它直接將用戶id賦值爲-1,會讓我在看到第一個函數時,就覺得它要獲取的是遊客信息,致使後面登陸失敗,當跳入到這個方法後(13行),我才發現它又重新在cookie裏面獲取了用戶id,

這裏的密碼有個小細節

 /// <summary>
        /// 返回論壇用戶密碼cookie明文
        /// </summary>
        /// <param name="key">密鑰</param>
        /// <returns></returns>
        public static string GetCookiePassword(string key)
        {
            return DES.Decode(GetCookie("password"), key).Trim();
        }

返回的是密碼明文,也就是我最開始說的那個密碼要保存加密後的,Discuz!nt會將你保存在cookie裏的密碼解密,它的實現方式是這樣的,先將 123456用md5加密成密文,再將密文跟passwordkey,混合加密,而後把這段存入cookie的pwd,Discuz!nt再將cookie裏

的pwd取出,解密,根據uderid和pwd,獲取用戶信息.

到這裏Discuz!nt整合登陸就實現了.

相關文章
相關標籤/搜索