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

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

这里附上代码

  //登录
protected void btnLogin_Click(object sender, EventArgs e)
{
string username = un.Value.Trim();
string password = pwd.Value.Trim(); string apikey = "3b8ccea63030e2747abf5740b2f57350";//有Discuz后台管理扩展->通行证设置获得
string secret = "7d0a34cfa6f7e2175e03aead1c52fe4c";//同上
string url = "http://bbs.oyytv.com/";//你的bbs路径
string cookieDomain = "oyytv.com";//你的域名
DiscuzSession ds = new DiscuzSession(apikey, secret, url);
int id = ds.GetUserID(username);//根据用户名获取用户ID
//用户名存在
if (id > )
{
//取得用户数据库中的密码
string dbpassword = ds.GetUserInfo(id).Password;
//判断数据库中的密码和输入的密码是否一致
if (dbpassword == FormsAuthentication.HashPasswordForStoringInConfigFile(password, "MD5").ToLower())
{
//输入密码正确,则登录
ds.Login(id, dbpassword, true, , cookieDomain); Discuz.Config.GeneralConfigInfo config = Discuz.Config.GeneralConfigs.GetConfig(); //删除之前的错误登录信息
LoginLogs.DeleteLoginLog(DNTRequest.GetIP());
//根据积分公式刷新用户总积分
UserCredits.UpdateUserCredits(id);
//写入用户登录后的cookie
ForumUtils.WriteUserCookie(id, Utils.StrToInt(DNTRequest.GetString("expires"), -), config.Passwordkey, DNTRequest.GetInt("templateid", ), DNTRequest.GetInt("loginmode", -)); Response.Redirect("http://bbs.oyytv.com");
//更新用户最后动作,如不需要可不执行
//OnlineUsers.UpdateAction(olid, UserAction.Login.ActionID, 0, config.Onlinetimeout);
//更新该用户最后访问时间
// Users.UpdateUserLastvisit(id, DNTRequest.GetIP());
}
else
{ }
}
else
{ } }

这里有几个存在误解的地方

整合,因为Discuz!nt是用cookie来保存用户状态,通过设置cookie的Domain来进行子站间的跨域,这里整合说的统一登录,注册...,只是针对于子站间的跨域,就是说将一个论坛,包含在你现有系统上

代码第10行,设置的其实就是Domain值.

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

 /// <summary>
/// 登录
/// </summary>
/// <param name="uid"></param>
/// <param name="password"></param>
/// <param name="isMD5Passwd"></param>
/// <param name="expires"></param>
/// <param name="cookieDomain"></param>
public void Login(int uid, string password, bool isMD5Passwd, int expires, string cookieDomain)
{
User user = GetUserInfo(uid);
HttpCookie cookie = new HttpCookie("dnt");
cookie.Values["userid"] = user.UId.ToString();
cookie.Values["password"] = EncodePassword(password, isMD5Passwd);
cookie.Values["avatar"] = HttpUtility.UrlEncode(user.Avatar.ToString());
cookie.Values["tpp"] = user.Tpp.ToString();
cookie.Values["ppp"] = user.Ppp.ToString();
cookie.Values["invisible"] = user.Invisible.ToString();
cookie.Values["referer"] = "index.aspx";
cookie.Values["expires"] = expires.ToString();
if (expires > )
{
cookie.Expires = DateTime.Now.AddMinutes(expires);
}
cookie.Domain = cookieDomain;
cookie.Path = "/";
HttpContext.Current.Response.AppendCookie(cookie);
}

这里的登录只是存一个子站间可以互相访问的cookie而已,要注意的是22行的密码,应该保存加密后的密码而不是明文密码,否则会导致你存的cookie在discuz!nt验证失败.

这里我说说discuz!nt的验证方式,所有页面都继承于PageBase,在它的构造函数里面会获取用户信息,来判断用户是否是游客,还是普通用户,这里的判断标识是以userid来判断,-1表示游客

  public PageBase()
{
if (recordPageView)
PageViewStatistic(pagename); config = GeneralConfigs.GetConfig();
if (SpacePluginProvider.GetInstance() == null)
config.Enablespace = ;
if (AlbumPluginProvider.GetInstance() == null)
config.Enablealbum = ;
if (MallPluginProvider.GetInstance() == null)
config.Enablemall = ; LoadUrlConfig();
userid = Utils.StrToInt(ForumUtils.GetCookie("userid"), -);
//清空当前页面查询统计
#if DEBUG
Discuz.Data.DbHelper.QueryCount = ;
Discuz.Data.DbHelper.QueryDetail = "";
#endif
// 如果启用游客页面缓存,则对游客输出缓存页
if (userid == - && config.Guestcachepagetimeout > && GetUserCachePage(pagename))
return; AddMetaInfo(config.Seokeywords, config.Seodescription, config.Seohead); if (config.Nocacheheaders == )
{
System.Web.HttpContext.Current.Response.BufferOutput = false;
System.Web.HttpContext.Current.Response.ExpiresAbsolute = DateTime.Now.AddDays(-);
System.Web.HttpContext.Current.Response.Cache.SetExpires(DateTime.Now.AddDays(-));
System.Web.HttpContext.Current.Response.Expires = ;
System.Web.HttpContext.Current.Response.CacheControl = "no-cache";
System.Web.HttpContext.Current.Response.Cache.SetNoStore();
} //当为forumlist.aspx或forumindex.aspx,可能出现在线并发问题,这时系统会延时2秒
if ((pagename != "forumlist.aspx") && (pagename != "forumindex.aspx"))
oluserinfo = OnlineUsers.UpdateInfo(config.Passwordkey, config.Onlinetimeout);
else
{
try
{
oluserinfo = OnlineUsers.UpdateInfo(config.Passwordkey, config.Onlinetimeout);
}
catch
{
System.Threading.Thread.Sleep();
oluserinfo = OnlineUsers.UpdateInfo(config.Passwordkey, config.Onlinetimeout);
}
}

代码15行,先获取用户id,这里是从cookie里面获取的,然后再根据id,pwd获取用户信息(代码44行).

这里我们看看UpdateInfo函数,代码如下:

 /// <summary>
/// 用户在线信息维护。判断当前用户的身份(会员还是游客),是否在在线列表中存在,如果存在则更新会员的当前动,不存在则建立.
/// </summary>
/// <param name="passwordkey">用户密码</param
/// <param name="timeout">在线超时时间</param>
public static OnlineUserInfo UpdateInfo(string passwordkey, int timeout)
{
return UpdateInfo(passwordkey, timeout, -, "");
}

在这里,它又重载了一次,重载代码如下:

         /// <summary>
/// 用户在线信息维护。判断当前用户的身份(会员还是游客),是否在在线列表中存在,如果存在则更新会员的当前动,不存在则建立.
/// </summary>
/// <param name="passwordkey">论坛passwordkey</param>
/// <param name="timeout">在线超时时间</param>
/// <param name="passwd">用户密码</param>
public static OnlineUserInfo UpdateInfo(string passwordkey, int timeout, int uid, string passwd)
{
lock (SynObject)
{
OnlineUserInfo onlineuser = new OnlineUserInfo();
string ip = DNTRequest.GetIP();
int userid = TypeConverter.StrToInt(ForumUtils.GetCookie("userid"), uid);
string password = (Utils.StrIsNullOrEmpty(passwd) ? ForumUtils.GetCookiePassword(passwordkey) : ForumUtils.GetCookiePassword(passwd, passwordkey)); // 如果密码非Base64编码字符串则怀疑被非法篡改, 直接置身份为游客
if (password.Length == || !Utils.IsBase64String(password))
userid = -; if (userid != -)
{
onlineuser = GetOnlineUser(userid, password); //更新流量统计
if (!DNTRequest.GetPageName().EndsWith("ajax.aspx") && GeneralConfigs.GetConfig().Statstatus == )
Stats.UpdateStatCount(false, onlineuser != null); if (onlineuser != null)
{
if (onlineuser.Ip != ip)
{
UpdateIP(onlineuser.Olid, ip);
onlineuser.Ip = ip;
return onlineuser;
}
}
else
{
// 判断密码是否正确
userid = Users.CheckPassword(userid, password, false);
if (userid != -)
{
Discuz.Data.OnlineUsers.DeleteRowsByIP(ip);
CheckIp(ip);
return CreateUser(userid, timeout);
}
else
{
CheckIp(ip);
// 如密码错误则在在线表中创建游客
onlineuser = GetOnlineUserByIP(-, ip);
if (onlineuser == null)
return CreateGuestUser(timeout);
}
}
}
else
{
onlineuser = GetOnlineUserByIP(-, ip);
//更新流量统计
if (!DNTRequest.GetPageName().EndsWith("ajax.aspx") && GeneralConfigs.GetConfig().Statstatus == )
Stats.UpdateStatCount(true, onlineuser != null); if (onlineuser == null)
return CreateGuestUser(timeout);
} //onlineuser.Lastupdatetime = Utils.GetDateTime(); 为了客户端能够登录注释此句,如有问题再修改。
return onlineuser;
}
}

在这块,会产生极大的误解,因为前文已经说过,-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整合登录就实现了.

Discuz!nt整合心得的更多相关文章

  1. Discuz!NT 3.5.2正式版与Asp.net网站会员信息整合

    Discuz!NT 提供了很多对外的接口利于与别的网站进行整合,经本人亲测,觉得开放的接口还是挺到位的.开发.测试一次通过,只不过api文档寻找无门,只能自己琢磨,费了不少周折,不过,功夫不负有心人, ...

  2. (转)Discuz!NT图文安装教程

    不同目录下的安装方法根据目前大家对论坛的使用需求,在安装上面大致有三种情况,站点根目录下安装,站点虚拟目录下安装和站点子目录下安装. 1.根目录安装 根目录安装是最简单也是稳定系数最高的安装和使用方式 ...

  3. Discuz NT 架构剖析之Config机制

    接触了Discuz NT! 一段时间了,是时候做个总结了,标题好霸气,有木有? 都是托园子里的大牛代振军的福啊,哈哈哈哈. 首先论坛的信息不是完全存储在数据库里面的,一部分信息存储在config文件里 ...

  4. 从Discuz!NT项目文件结构看如何给系统框架分层和类库分文件夹

    以下为Discuz!NT的文件夹根目录: 类库图: 从上面两个图可以看出: 1.dnt对于类库的分层是通过名称的层级来区分的,如Discuz.Plugn和Discuz.Plugin.Spread 2. ...

  5. 对于Discuz!NT不允许新用户注册的解决办法

    客户论坛用的是Discuz!NT,但是用户注册总是提示不允许新用户注册,对于这个问题,网上好多说的是管理员登录后台,在"用户与访问控制"里将允许新用户注册改为"是&quo ...

  6. Discuz!NT 3.9.913 Beta DIY过程

    前提: 论坛的源码版本为dnt_3.9.913_sqlserver_beta.zip,以下例子都以这个版本为原型修改 dnt_3.9.913数据字典:下载 目前(2013年10月21日)官网的asp. ...

  7. .net mvc通过ucenter和 discuz的整合,nopcommerce ucenter 插件的方式实现

    discuz无疑是目前市面上最好的论坛之一,对于大多数公司来说,用discuz搭建一个论坛肯定是最节约成本的选择,然而我们的会员想要和discuz进行整合的话,只有两种荀泽,一种直接选用discuz的 ...

  8. Discuz!NT 后台任意文件上传的源代码修补方法

    相关的漏洞介绍: http://www.wooyun.org/bugs/wooyun-2013-035199 Discuz!NT 管理后台可以自定义文件类型,从而造成任意文件上传,测试过程中 aspx ...

  9. Discuz!NT静态文件缓存(SQUID)

    在目前最新版本的产品中,我们提供了缓存静态文件的解决方案,就是使用SQUID做静态前端,将论坛中的大部分静态文件布署或外链到一个新的HTTP链接上,其中可以外链的静态文件包括:      1.Disc ...

随机推荐

  1. Web.config配置文件详解(新手必看)

    花了点时间整理了一下ASP.NET Web.config配置文件的基本使用方法.很适合新手参看,由于Web.config在使用很灵活,可以自定义一些节点.所以这里只介绍一些比较常用的节点. <? ...

  2. Aspose.Words组件介绍及使用—基本介绍与DOM概述

    1.基本介绍 Aspose.Words是一个商业.NET类库,可以使得应用程序处理大量的文件任务.Aspose.Words支持Doc,Docx,RTF,HTML,OpenDocument,PDF,XP ...

  3. haproxy配置直接重定向url

    在邮件列表看到有个人问haproxy能否在接到一个请求时选择一个后端服务器,然后301重定向url .主要原因是他有5个1G的出口,这样就能充分利用其带宽.测试了一下是可以的 frontend fre ...

  4. 深入理解OAuth2.0

    1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...

  5. TinyXml和tinyxml2

    C++操作xml没有标准库的支持,TinyXml是个不错的xml操作库,以前总是使用TinyXml读写xml,但是最近对大量xml进行读写时,速度真的是有点慢,特别是在调试时,每次启动读xml就要好长 ...

  6. CentOS6.4下Git服务器Gitosis安装配置

    1.安装GIt: #yum install git 2.增加一个git用户 #useradd git #passwd git 3.创建git仓库存储目录,设置权限 #mkdir /home/git/r ...

  7. .net软件自动化测试笔记(API-1)

    .net 软件测试自动化之道 API(Application Programming Interface)包括单元测试(Unit Testing),模块测试(Module Testing),组件测试( ...

  8. 【JS】Intermediate1:The DOM

    1.DOM(The Document Object Model) A way to manipulate the structure and style of an HTML page. It rep ...

  9. Esper系列(八)Method Definition、Schema

    Method Definition 作用:以公共静态方法的方式去访问外部数据.   应用说明: 1.返回数据的方法必须是公共静态方法(方法参数可以有多个也可以没有): 2.如果返回一条数据或无返回数据 ...

  10. poj3177--Redundant Paths(边的双连通)

    有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路.两条独立的路是指:没有公共边的路,但可以 ...