论坛首页 综合技术论坛

powerd by discuz 7.2 论坛自动发帖原理介绍

浏览 21005 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-01-07   最后修改:2011-01-07

     现在很多论坛都是使用现成的 powerd by discuz 7.2,虽说 readme 里声明不是免费软件,但是也没看到要收费的地方,对小公司而言,要搭建一个 BBS 论坛,Linux + Apache + Mysql + PHP + Discuz 无疑是很不错的选择,上手容易,配置也不复杂。

      上一帖给出了在discuz的论坛上自动发帖的代码,这里介绍一下它的基本原理吧。(参见附件的图片)

 

  • 获取登录的 sid 和 formhash 。

      这是个 GET 请求,请求页面 http://192.168.72.130/bbs/logging.php?action=login,服务端返回 sid 和 formhash,其中 sid 是会话的 ID,在返回的 Cookie 中,读取头部的 Set-Cookie 部分即可,sid 每次请求页面,值都不一样;formhash 在返回的文本文件中,如果在浏览器中直接输入:http://192.168.72.130/bbs/logging.php?action=login,可以看到登录界面,查看-源文件,找到登录的那个表单 form ,其中的 input 就有 formhash,type=hidden,隐藏不可见,formhash的值为8位的字母数字搭配,这是服务器返回给客户端的身份标识,具体算法好像是根据时间戳等信息,求MD5后,取其中8位,具体细节参照 discuz 的 PHP 源码吧。

 

 

  • 登录,获取 auth。

      有了 formhash 就可以登录了,其实登录的目的就是为了获得 auth 值,auth 值是通过服务器返回的 Cookie 中获得的。登录的过程是发送 POST 请求,首先要将 sid 写入 Cookie 中,POST 的内容可以通过在 URL 中传输,或是在 POST 的文本内容中,传递的参数有 action, loginfield, questionid, answer, loginsubmit, formhash, username, password 等,相互之间用 & 连接,这些参数在登录界面的源代码里都可以找到,具体内容可以参考代码:

 

"action=login&loginfield=username&questionid=0&answer=&loginsubmit=yes&formhash="
       + login_formhash
       + "&username="
       + user
       + "&password=" + pass

 

     其实以上过程就是模拟浏览器,发送 POST 请求,点击“登录”按钮的时候,浏览器完成以上动作,这里由代码自动完成。

     此时,服务器就认可了用户已经登录,将会保存用户已登录的信息,服务端回应的 Cookie 中,包含了 auth 值,需要从 Cookie 中提取并保存,作为用户的身份标识,用作后续的发帖身份认证。

 

  • 获取发帖的 formhash。

     登录到服务器后,要进行发帖操作,需要得到一个 formhash 标识,通过 GET 请求页面 http://192.168.72.130/bbs/post.php?action=newthread&fid=10 ,其中包含了 fromhash 值,这个请求要包含 sid 和 auth 的 Cookie,其中 fid=10 意为版块的 ID ,可以通过登录具体的版块发帖,鼠标放在“发帖”按钮上,浏览器状态栏会显示 ID 号,或者在发帖页面,查看源文件,找到发帖的表单 form ,查看这个 ID  号。

     服务器返回的内容中,会有个表单,包含 formhash 值,至此,就可以进行发帖操作了。

 

  • 发帖。

     发帖操作和登录操作类似,通过 POST 请求页面 http://192.168.72.130/bbs/post.php,同样需要把 Cookies 的内容加上;具体 POST 的内容,可以参考发帖操作页面的源代码,其中 form 的内容就是要 POST 的内容。可以参考如下:

 

"action=newthread&topicsubmit=yes&subject=" + subject
     + "&formhash=" + post_formhash + "&fid=" + new_fid
     + "&message=" + msg

 

     服务器会返回发帖的结果,所以有必要接受服务返回的内容,用来测试是否发帖成功。具体功能就不实现了。

 

  • 总结

     至此,自动发帖的原理就介绍完了。

     基本的过程就是,GET 请求登录页面,Cookie 中获得 sid ,返回页面中获得 formhash,用 sid formhash username ... 等信息,发送 POST 请求登录,登录后 Cookie 中会有 auth 等信息,取得 auth 后,GET 请求发帖页面,在页面中获得 formhash ,再以 sid auth ...等发送 POST 请求,完成发帖操作。

     如果有笔误或讲得不对的地方,请网友指教。

 

     附上 wireshark 网络抓包的部分内容,供参考。

 

Expert Info (Chat/Sequence): GET /bbs/logging.php?action=login HTTP/1.1\r\n

HTTP/1.1 200 OK\r\n
CsN_sid=RkWOSy; expires=Thu, 13-Jan-2011 09:26:26 GMT; path=/; httponly
<input type="hidden" name="formhash" value="dc5dc9b8" />\r\n

 

Expert Info (Chat/Sequence): POST /bbs/logging.php HTTP/1.1\r\n
CsN_sid=RkWOSy
action=login&formhash=dc5dc9b8&loginfield=username&questionid=0&answer=&loginmode=normal&loginsubmit=true&username=test&password=test

HTTP/1.1 200 OK\r\n
CsN_auth=0d5eTSofQlbIT7ENDULLpdt%2FCi3ysya4vt3LHVIVY%2BRnUAsxR5Gx8R4TOmcS7yXSVjsJ1BUG%2BVb0THYVj5YagA; expires=Sun, 03-Jan-2021 09:26:37 GMT; path=/; httponly
<a href="logging.php?action=logout&amp;formhash=dc5dc9b8">\315\313\263\366</a>\r\n

 

GET /bbs/post.php?action=newthread&fid=10&extra=page%3D1 HTTP/1.1\r\n
CsN_sid=RkWOSy; CsN_auth=0d5eTSofQlbIT7ENDULLpdt%2FCi3ysya4vt3LHVIVY%2BRnUAsxR5Gx8R4TOmcS7yXSVjsJ1BUG%2BVb0THYVj5YagA

HTTP/1.1 200 OK\r\n
<input type="hidden" name="formhash" id="formhash" value="570a67c4" />\r\n
<input type="hidden" name="posttime" id="posttime" value="1294306004" />\r\n
<input type="hidden" name="wysiwyg" id="e_mode" value="0" />\r\n
<input type="hidden" name="iconid" id="iconid" value="" />\r\n

 

POST /bbs/post.php HTTP/1.1\r\n
CsN_sid=RkWOSy; CsN_auth=0d5eTSofQlbIT7ENDULLpdt%2FCi3ysya4vt3LHVIVY%2BRnUAsxR5Gx8R4TOmcS7yXSVjsJ1BUG%2BVb0THYVj5YagA
action=reply&replysubmit=yes&replysubmit=true&formhash=570a67c4&fid=10&tid=15&subject=&message=6666666666666666666666666

HTTP/1.1 200 OK\r\n
CsN_oldtopics=D15D; expires=Thu, 06-Jan-2011 10:27:06 GMT; path=/
CsN_fid10=1294306025; expires=Thu, 06-Jan-2011 10:27:06 GMT; path=/
CsN_visitedfid=10; expires=Sat, 05-Feb-2011 09:27:06 GMT; path=/

    

  • 大小: 15.1 KB
   发表时间:2011-01-10  
能不能研究下如何回帖?
http://iliuw.iteye.com/blog/636505
这里的代码不完整,不知道怎么得到某个帖子的formhash
特别是他的getRecLink(buildId)是如何实现的不知道!
0 请登录后投票
   发表时间:2011-01-12  
    你给的地址中使用了 httpclient 这个 jar 的辅助包,我是直接使用 java 提供的HttpUrlConnection 类,自己构造一个 POST 请求,这样对网络的数据通信理解得也更透彻些,回帖也实现了,没时间整理发到博客上来。
    要查看某个帖子的formhash,要登录到这个帖子,得到版块 ID 和帖子 ID,也就是 fid和 tid,把鼠标放在版块或是帖子标题上,状态栏会显示的。知道 fid 和 tid 了,就可以发请求,得到一个发帖页面,从这个页面中提取 formhash 。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics