jd_sms_login/index.js

314 lines
8.4 KiB
JavaScript
Raw Normal View History

2022-03-08 18:07:26 +08:00
// 填入你的配置,或者通过环境变量传入
const QYWX_KEY =
process.env.QYWX_KEY && process.env.QYWX_KEY.length > 0
? process.env.QYWX_KEY
: '';
// 尽量不用@all除非只有你一个人
const QYWX_AM =
process.env.QYWX_AM && process.env.QYWX_AM.length > 0
? process.env.QYWX_AM
: '';
const express = require('express');
const got = require('got');
const path = require('path');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
const crypto = require('crypto');
const md5 = function (str) {
const encode = crypto.createHash('md5');
return encode.update(str).digest('hex');
};
/**
* 发送消息推送
*
* @param {*} msg
*/
async function sendMsg(updateMsg, cookie, userMsg) {
// 企业微信群机器人
if (QYWX_KEY) {
try {
await got.post(
`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${QYWX_KEY}`,
{
responseType: 'json',
json: {
msgtype: 'text',
text: {
content: `====获取到cookie====\n${updateMsg}\n用户备注:${userMsg}\n${cookie}`,
},
},
}
);
} catch (err) {
console.log({
msg: '企业微信群机器人消息发送失败',
});
}
}
if (QYWX_AM) {
try {
const [corpid, corpsecret, userId, agentid] = QYWX_AM.split(',');
const getToken = await got.post({
url: `https://qyapi.weixin.qq.com/cgi-bin/gettoken`,
json: {
corpid,
corpsecret,
},
headers: {
'Content-Type': 'application/json',
},
timeout: 10000,
});
const accessToken = JSON.parse(getToken.body).access_token;
const res = await got.post({
url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${accessToken}`,
json: {
touser: userId,
agentid,
safe: '0',
msgtype: 'text',
text: {
content: `====获取到cookie====\n${updateMsg}\n用户备注:${userMsg}\n${cookie}`,
},
},
headers: {
'Content-Type': 'application/json',
},
timeout: 10000,
});
} catch (err) {
console.log({
msg: '企业微信应用消息发送失败',
});
}
}
}
/**
* 对ck进行处 的流程
*
* @param {*} cookie
* @return {*}
*/
async function cookieFlow(cookie, userMsg) {
try {
await sendMsg(updateMsg, cookie, userMsg);
return msg;
} catch (err) {
return '';
}
}
async function sendSms(phone) {
let appid = 959;
let version = '1.0.0';
let countryCode = 86;
let timestamp = new Date().getTime();
let subCmd = 1;
let gsalt = 'sb2cwlYyaCSN1KUv5RHG3tmqxfEb8NKN';
let gsign = md5('' + appid + version + timestamp + '36' + subCmd + gsalt);
let res = await got.post('https://qapplogin.m.jd.com/cgi-bin/qapp/quick', {
method: 'post',
headers: {
'user-agent':
'Mozilla/5.0 (Linux; Android 10; V1838T Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.87 Mobile Safari/537.36 hap/1.9/vivo com.vivo.hybrid/1.9.6.302 com.jd.crplandroidhap/1.0.3 ({packageName:com.vivo.hybrid,type:deeplink,extra:{}})',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
'accept-encoding': '',
cookie: '',
},
body:
'client_ver=' +
version +
'&gsign=' +
gsign +
'&appid=' +
appid +
'&return_page=https%3A%2F%2Fcrpl.jd.com%2Fn%2Fmine%3FpartnerId%3DWBTF0KYY%26ADTAG%3Dkyy_mrqd%26token%3D&cmd=36&sdk_ver=1.0.0&sub_cmd=' +
subCmd +
'&qversion=' +
version +
'&ts=' +
timestamp,
dataType: 'json',
});
let data = JSON.parse(res.body).data;
subCmd = 2;
timestamp = new Date().getTime();
gsalt = data.gsalt;
gsign = md5('' + appid + version + timestamp + '36' + subCmd + gsalt);
let sign = md5(
'' +
appid +
version +
countryCode +
phone +
'4dtyyzKF3w6o54fJZnmeW3bVHl0$PbXj'
);
let ck =
'guid=' +
data.guid +
';lsid=' +
data.lsid +
';gsalt=' +
data.gsalt +
';rsa_modulus=' +
data.rsa_modulus +
';';
res = await got.post('https://qapplogin.m.jd.com/cgi-bin/qapp/quick', {
method: 'post',
headers: {
'user-agent':
'Mozilla/5.0 (Linux; Android 10; V1838T Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.87 Mobile Safari/537.36 hap/1.9/vivo com.vivo.hybrid/1.9.6.302 com.jd.crplandroidhap/1.0.3 ({packageName:com.vivo.hybrid,type:deeplink,extra:{}})',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
'accept-encoding': '',
cookie: ck,
},
body:
'country_code=' +
countryCode +
'&client_ver=' +
version +
'&gsign=' +
gsign +
'&appid=' +
appid +
'&mobile=' +
phone +
'&sign=' +
sign +
'&cmd=36&sub_cmd=' +
subCmd +
'&qversion=' +
version +
'&ts=' +
timestamp,
dataType: 'json',
});
data = JSON.parse(res.body).data;
if (data.err_code > 0) {
return { ok: false, msg: '发送验证码失败:' + data.err_msg };
} else {
return { ok: true, msg: 'success', data: { ck: ck, gsalt: gsalt } };
}
}
async function checkCode(phone, code, gsalt, ck) {
let appid = 959;
let version = '1.0.0';
let countryCode = 86;
let timestamp = new Date().getTime();
let subCmd = 3;
let gsign = md5('' + appid + version + timestamp + '36' + subCmd + gsalt);
let body =
'country_code=' +
countryCode +
'&client_ver=' +
version +
'&gsign=' +
gsign +
'&smscode=' +
code +
'&appid=' +
appid +
'&mobile=' +
phone +
'&cmd=36&sub_cmd=' +
subCmd +
'&qversion=' +
version +
'&ts=' +
timestamp;
res = await got.post('https://qapplogin.m.jd.com/cgi-bin/qapp/quick', {
method: 'post',
headers: {
'user-agent':
'Mozilla/5.0 (Linux; Android 10; V1838T Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.87 Mobile Safari/537.36 hap/1.9/vivo com.vivo.hybrid/1.9.6.302 com.jd.crplandroidhap/1.0.3 ({packageName:com.vivo.hybrid,type:deeplink,extra:{}})',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
'accept-encoding': '',
cookie: ck,
},
body: body,
dataType: 'json',
});
let data = JSON.parse(res.body);
return data;
}
/**
* API 发验证码
*/
app.get('/sendSms', async function (request, response) {
try {
const phone = request.query.phone;
if (!new RegExp('\\d{11}').test(phone)) {
response.send({ ok: false, msg: '手机号格式错误' });
return;
}
console.log(phone);
const data = await sendSms(phone);
response.send(data);
} catch (err) {
console.log(err);
response.send({ ok: false, msg: '错误' });
}
});
app.post('/checkCode', async function (request, response) {
try {
const phone = request.query.phone;
if (!new RegExp('\\d{11}').test(phone)) {
response.send({ ok: false, msg: '手机号格式错误' });
return;
}
const code = request.query.code;
if (!new RegExp('\\d{6}').test(code)) {
response.send({ ok: false, msg: '验证码格式错误' });
return;
}
const { gsalt, ck } = request.body;
console.log(phone, code);
const data = await checkCode(phone, code, gsalt, ck);
if (data.err_code > 0) {
response.send({ ok: false, msg: '登录失败:' + r.err_msg });
} else {
const cookie =
'pt_key=' +
data.data.pt_key +
';pt_pin=' +
encodeURIComponent(data.data.pt_pin) +
';';
await cookieFlow(cookie, '短信登录');
response.send({
ok: true,
msg: '获取ck成功',
data: {
ck: cookie,
},
});
}
} catch (err) {
console.log(err);
response.send({ ok: false, msg: '错误' });
}
});
const sleep = (ms) => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
};
app.use(express.static(path.join(__dirname, 'public')));
const PORT = 6789;
app.listen(PORT, () => {
console.log(`应用正在监听 ${PORT} 端口!`);
});