zoukankan      html  css  js  c++  java
  • Discuz!nt整合心得

    最近研究了下Discuz!nt的整合,因为是网上找的实例,有个地方的写错了,导致纠结了一整天,这里分享出来.

    Discuz!nt提供了整合工具DiscuzToolkit,用于调用Discuz!nt API的一款工具,网上能够很轻松的找到源码,但是项目中需要引用几个DLL,如图

    这里附上代码

     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值.

    第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验证失败.

    这里我说说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整合登录就实现了.

  • 相关阅读:
    Linnia学习记录
    漫漫考研路
    ENS的学习记录
    KnockoutJS 3.X API 第四章 数据绑定(4) 控制流with绑定
    KnockoutJS 3.X API 第四章 数据绑定(3) 控制流if绑定和ifnot绑定
    KnockoutJS 3.X API 第四章 数据绑定(2) 控制流foreach绑定
    KnockoutJS 3.X API 第四章 数据绑定(1) 文本及样式绑定
    KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册
    KnockoutJS 3.X API 第三章 计算监控属性(4)Pure computed observables
    KnockoutJS 3.X API 第三章 计算监控属性(3) KO如何实现依赖追踪
  • 原文地址:https://www.cnblogs.com/tibos/p/5362712.html
Copyright © 2011-2022 走看看