DZ论坛登陆协议分析及源码分享
# 说明
这玩意就是难追,各种Cookie,带入不对就得不到想要的内容,所以能带的都带入了。就是找协议时容易出错,重写了三遍代码才写出来,全程POST请求及GET请求,不调用第三方控件,保持稳定性。 找了很多,论坛内并没有找到这种DZ的登陆协议,发布出来,为自己留个备份,也为论坛添砖加瓦,本文为node.js. 本文以吾爱破解论坛为例,具体版本未知。其他论坛自测!
# 请求登陆页[GET]
地址:https://www.52pojie.cn/member.php?mod=logging&action=login
# axios携带请求头:
var config = {
method: 'get',
url: 'https://www.52pojie.cn/member.php?mod=logging&action=login&referer=https%3A%2F%2Fwww.52pojie.cn%2Findex.php',
headers: {
'User-Agent': 'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/65.0.3314.0Safari/537.36SE2.XMetaSr1.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Referer': 'https://www.52pojie.cn/member.php?mod=logging&action=login"',
'Host': 'www.52pojie.cn',
'Connection': 'keep-alive',
// 下面这一行很重要 详细看注意模块
"Accept-Encoding": "gzip,deflate,compress"
}
}
request(config).then((res) => {
console.log(res)
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 返回源码后取参数
request(config).then((res) => {
console.log(res)
// 生成全局变量 _hash _Login_hash
_hash = res.split('name="formhash" value="')[1].split('" />')[0]
_Login_hash = res
.split('loginsubmit=yes&loginhash=')[1]
.split('">')[0]
})
2
3
4
5
6
7
8
取name="formhash" value=" 与 " />
之间的内容,保存为全局变量_hash
取loginsubmit=yes&loginhash= 与 ">
之间的内容,保存为全局变量_Login_hash
# 返回头中Set-Cookie中取:
//
// _saltkey = cookie[0].split(';')[0].split('2iZO_2132_saltkey=')[1]
// 我这里使用拦截器 直接循环获取
let otherInfo={}
request.interceptors.response.use(function (response) {
let cookie = response.headers['set-cookie']
cookie.forEach(item=>{
let str = item.split(';')[0]
let key = str.split('=')[0]
let value = str.split('=')[1]
otherInfo[key] = value
// console.log(cookie[0].split(';')[0])
})
})
console.log(otherInfo)
// {
// htVD_2132_saltke:xxx,
// htVD_2132_lastact:xxx,
// htVD_2132_lastvisit:xxx
// }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 请求验证码[GET]
地址:https://www.52pojie.cn/misc.php?mod=seccode&action=update&idhash=cS&0.01289042" & 全局变量_随机数 & "&modid=member::logging"
在这个地方看到了有我的一个随机数,这个随机数十位
,搞个全局变量在初始时在过程中生成即可。
根绝不同论坛,这个随机数位数也可能不一致,根据自己的需求改吧
# 携带请求头:
// 链接中的随机数 我这里15位 (参数 1000000000000000 可以控制随机数位数
let num = Math.round(Math.random() * 1000000000000000) / 1000000000000000
let otherInfo ={
// htVD_2132_saltke:xxx,
// htVD_2132_lastact:xxx,
// htVD_2132_lastvisit:xxx
}
// Cookie 从上面拦截器中已经获取储存到 这里拼出来
let Cookie=''
let keys = Object.keys(otherInfo)
keys.forEach(item=>{
Cookie += `${item}=${otherInfo[item]}; `
})
const config = {
url: `https://www.52pojie.cn/misc.php?mod=seccode&action=update&referer=https%3A%2F%2Fwww.52pojie.cn%2Findex.php&idhash=cSDU4gdY&${num}&modid=member::logging`,
method: 'get',
headers: {
'User-Agent':
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/65.0.3314.0Safari/537.36SE2.XMetaSr1.0',
Accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
Referer: 'https://www.52pojie.cn/member.php?mod=logging&action=login"',
Cookie: Cookie,
Host: 'www.52pojie.cn',
Connection: 'keep-alive',
'Accept-Encoding': 'gzip,deflate,compress',
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
本次携带的请求头中的Cookie中全局变量为“请求登陆页”中所保存的全局变量。
# 返回源码,取验证码的URL地址:
取height="50" src=" 与 " class="vm" alt=""(这里根据网站不同需要具体查看源码中的参数例如高度是否一致) 之间的内容保存为验证码地址变量 然后"https://www.52pojie.cn/" 与 验证码地址变量做一个拼接,形成了一个完整的验证码地址。
# 返回头中Set-Cookie中取:
全局变量_lastact = Split(Split(TEMP, "htVD_2132_lastact=")(1), ";")(0)
# 下载验证码[GET]
地址:上文中所获得的验证码地址 携带请求头:
const config = {
url: url,
method: 'get',
responseType: "arraybuffer",
headers: {
'User-Agent':
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/65.0.3314.0Safari/537.36SE2.XMetaSr1.0',
Accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
Referer: 'https://www.52pojie.cn/member.php?mod=logging&action=login"',
Cookie: Cookie,
'Accept-Encoding': 'gzip,deflate,compress',
},
}
request(config).then(res=>{
fs.writeFile(`images/${Date.now()}.png`, buffer, {}, (err, res) => {
// 保存完成或者报错做处理;
})
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 验证验证码是否正确
地址:"https://www.52pojie.cn/misc.php?mod=seccode&action=check&inajax=1&modid=member::logging&idhash=cS&secverify=abcd" 地址中的abcd为验证码内容
携带请求头:
const config = {
url: `https://www.52pojie.cn/misc.php?mod=seccode&action=check&inajax=1&modid=member::logging&idhash=${loginInfo._Ceccode_hash}&secverify=${code}`,
method: 'get',
headers: {
'User-Agent':
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/65.0.3314.0Safari/537.36SE2.XMetaSr1.0',
Cookie: Cookie,
Accept: '*/*',
Host: 'www.52pojie.cn',
Connection: 'keep-alive',
'Accept-Encoding': 'gzip,deflate,compress',
},
}
request(config).then(res=>{
// console.log('验证码是否正确', res)
if(res.indexOf('succeed')>=0){
console.log('验证成功')
login(code)
}else{
console.log('验证失败')
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 登陆[POST]
地址:"https://www.52pojie.cn/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=" & 全局变量_Login_hash & "&inajax=1" 全局变量_Login_hash 第一步就已经找出来了,代入进去。
# 携带请求头:
const config = {
url: `https://34king.life/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=${loginInfo._Login_hash}&inajax=1`,
method: 'post',
headers: {
'User-Agent':
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/65.0.3314.0Safari/537.36SE2.XMetaSr1.0',
Cookie: Cookie,
Accept: '*/*',
Host: 'www.52pojie.cn',
Connection: 'keep-alive',
'Content-Type': 'multipart/form-data',
'Accept-Encoding': 'gzip,deflate,compress',
},
data,
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 携带参数
// node 没有new FormData 需要装依赖 npm
let data = new FormData()
data.append('username', '')//证号
data.append('password', '')//密码
data.append('referer', 'https://www.52pojie.cn/index.php')
data.append('questionid', '0')
data.append('answer', '')
data.append('seccodehash', loginInfo._Ceccode_hash) //前面存的hash
data.append('seccodemodid', 'member::logging')
data.append('formhash', loginInfo._Form_hash)
data.append('seccodeverify', code) //验证码
2
3
4
5
6
7
8
9
10
11
# 请求
request(config ).then((res) => {
console.log(res)
})
2
3
# 注意
# 使用node.js 中的axios进行请求时会爆出AxiosError: unexpected end of file
原文地址 (opens new window)
解决方法:
方法1 :降级至axios1.20
方法2 : axios 添加如下配置
axios.get("url", {
headers: { "Accept-Encoding": "gzip,deflate,compress" }
});
2
3