From 7f7d4d4f2438b5d8181d71061e301af234e941eb Mon Sep 17 00:00:00 2001 From: whyour Date: Tue, 16 Mar 2021 14:46:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0cookie=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/config.ts | 29 +------ back/api/cookie.ts | 32 +++++++ back/config/util.ts | 28 ++++++ back/loaders/express.ts | 1 + back/services/cookie.ts | 170 +++++++++++++++++++++++++++++++++++++ package.json | 1 + src/pages/cookie/index.tsx | 77 ++++++++++------- 7 files changed, 279 insertions(+), 59 deletions(-) create mode 100644 back/config/util.ts diff --git a/back/api/config.ts b/back/api/config.ts index c3f264ca..a8168937 100644 --- a/back/api/config.ts +++ b/back/api/config.ts @@ -1,7 +1,7 @@ +import { getFileContentByName, getLastModifyFilePath } from '../config/util'; import { Router, Request, Response, NextFunction } from 'express'; import { Container } from 'typedi'; import { Logger } from 'winston'; -import * as fs from 'fs'; import config from '../config'; const route = Router(); @@ -41,30 +41,3 @@ export default (app: Router) => { }, ); }; - -function getFileContentByName(fileName) { - if (fs.existsSync(fileName)) { - return fs.readFileSync(fileName, 'utf8'); - } - return ''; -} -function getLastModifyFilePath(dir) { - var filePath = ''; - - if (fs.existsSync(dir)) { - var lastmtime = 0; - - var arr = fs.readdirSync(dir); - - arr.forEach(function (item) { - var fullpath = path.join(dir, item); - var stats = fs.statSync(fullpath); - if (stats.isFile()) { - if (stats.mtimeMs >= lastmtime) { - filePath = fullpath; - } - } - }); - } - return filePath; -} diff --git a/back/api/cookie.ts b/back/api/cookie.ts index 3891c576..3123c99e 100644 --- a/back/api/cookie.ts +++ b/back/api/cookie.ts @@ -3,6 +3,8 @@ import { Container } from 'typedi'; import CookieService from '../services/cookie'; import { celebrate, Joi } from 'celebrate'; import { Logger } from 'winston'; +import { getFileContentByName } from '../config/util'; +import config from '../config'; const route = Router(); export default (app: Router) => { @@ -25,4 +27,34 @@ export default (app: Router) => { } }, ); + + route.get( + '/cookies', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cookieService = Container.get(CookieService); + const data = await cookieService.getCookies(); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.get( + '/cookie', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cookieService = Container.get(CookieService); + const data = await cookieService.addCookie(); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); }; diff --git a/back/config/util.ts b/back/config/util.ts new file mode 100644 index 00000000..5c7d2886 --- /dev/null +++ b/back/config/util.ts @@ -0,0 +1,28 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +export function getFileContentByName(fileName: string) { + if (fs.existsSync(fileName)) { + return fs.readFileSync(fileName, 'utf8'); + } + return ''; +} + +export function getLastModifyFilePath(dir: string) { + let filePath = ''; + + if (fs.existsSync(dir)) { + const arr = fs.readdirSync(dir); + + arr.forEach((item) => { + var fullpath = path.join(dir, item); + var stats = fs.statSync(fullpath); + if (stats.isFile()) { + if (stats.mtimeMs >= 0) { + filePath = fullpath; + } + } + }); + } + return filePath; +} diff --git a/back/loaders/express.ts b/back/loaders/express.ts index f576c860..c521371c 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -10,6 +10,7 @@ export default ({ app }: { app: Application }) => { app.use(cors()); app.use(bodyParser.json()); + app.use(bodyParser.urlencoded({ extended: true })); app.use( jwt({ secret: config.secret as string, algorithms: ['HS384'] }).unless({ path: ['/api/auth'], diff --git a/back/services/cookie.ts b/back/services/cookie.ts index 6dc262bc..005c3059 100644 --- a/back/services/cookie.ts +++ b/back/services/cookie.ts @@ -1,6 +1,15 @@ import { Service, Inject } from 'typedi'; import winston from 'winston'; import fetch from 'node-fetch'; +import { getFileContentByName } from '../config/util'; +import config from '../config'; +import FormData from 'form-data'; + +enum Status { + '正常', + '失效', + '状态异常', +} @Service() export default class CookieService { @@ -122,4 +131,165 @@ export default class CookieService { this.lstoken + '; '; } + + private getCookie(response: any) { + var TrackerID = response.headers['set-cookie'][0]; + TrackerID = TrackerID.substring( + TrackerID.indexOf('=') + 1, + TrackerID.indexOf(';'), + ); + var pt_key = response.headers['set-cookie'][1]; + pt_key = pt_key.substring(pt_key.indexOf('=') + 1, pt_key.indexOf(';')); + var pt_pin = response.headers['set-cookie'][2]; + pt_pin = pt_pin.substring(pt_pin.indexOf('=') + 1, pt_pin.indexOf(';')); + var pt_token = response.headers['set-cookie'][3]; + pt_token = pt_token.substring( + pt_token.indexOf('=') + 1, + pt_token.indexOf(';'), + ); + var pwdt_id = response.headers['set-cookie'][4]; + pwdt_id = pwdt_id.substring(pwdt_id.indexOf('=') + 1, pwdt_id.indexOf(';')); + var s_key = response.headers['set-cookie'][5]; + s_key = s_key.substring(s_key.indexOf('=') + 1, s_key.indexOf(';')); + var s_pin = response.headers['set-cookie'][6]; + s_pin = s_pin.substring(s_pin.indexOf('=') + 1, s_pin.indexOf(';')); + this.cookies = + 'TrackerID=' + + TrackerID + + '; pt_key=' + + pt_key + + '; pt_pin=' + + pt_pin + + '; pt_token=' + + pt_token + + '; pwdt_id=' + + pwdt_id + + '; s_key=' + + s_key + + '; s_pin=' + + s_pin + + '; wq_skey='; + var userCookie = 'pt_key=' + pt_key + ';pt_pin=' + pt_pin + ';'; + console.log('\n############ 登录成功,获取到 Cookie #############\n\n'); + console.log('Cookie1="' + userCookie + '"\n'); + console.log('\n####################################################\n\n'); + return userCookie; + } + + public async addCookie() { + const cookie: any = await this.checkLogin(); + if (cookie.body.errcode == 0) { + let ucookie = this.getCookie(cookie); + return ucookie; + } else { + return ''; + } + } + + private async checkLogin() { + try { + if (this.cookies == '') { + return 0; + } + let timeStamp = new Date().getTime(); + let url = + 'https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=' + + this.token + + '&ou_state=0&okl_token=' + + this.okl_token; + let payload = { + lang: 'chs', + appid: 300, + returnurl: + 'https://wqlogin2.jd.com/passport/LoginRedirect?state=1100399130787&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action', + source: 'wq_passport', + }; + let form = new FormData(); + for (const key in payload) { + form.append(key, (payload as any)[key] as any); + } + const response = await fetch(url, { + method: 'post', + body: form, + headers: { + Referer: + 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=' + + timeStamp + + '&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport', + Cookie: this.cookies, + Connection: 'Keep-Alive', + 'Content-Type': 'application/x-www-form-urlencoded; Charset=UTF-8', + Accept: 'application/json, text/plain, */*', + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36', + }, + }); + + return response; + } catch (error) { + console.log(error.response.body); + let res: any = {}; + res.body = { check_ip: 0, errcode: 222, message: '出错' }; + res.headers = {}; + return res; + } + } + + public async getCookies() { + const content = getFileContentByName(config.confFile); + const regx = /Cookie[0-9]{1}\=\"(.+?)\"/g; + let m, + data = []; + while ((m = regx.exec(content)) !== null) { + data.push(m[1]); + } + return this.formatCookie(data); + } + + private async formatCookie(data: any[]) { + const result = []; + for (const x of data) { + const { nickname, status } = await this.getJdInfo(x); + result.push({ + pin: x.match(/pt_pin=(.+?);/)[1], + cookie: x, + status, + nickname: nickname, + }); + } + return result; + } + + private getJdInfo(cookie: string) { + return fetch( + `https://me-api.jd.com/user_new/info/GetJDUserInfoUnion?orgFlag=JD_PinGou_New&callSource=mainorder&channel=4&isHomewhite=0&sceneval=2&_=${Date.now()}&sceneval=2&g_login_type=1&g_ty=ls`, + { + method: 'get', + headers: { + Accept: '*/*', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'zh-cn', + Connection: 'keep-alive', + Cookie: cookie, + Referer: 'https://home.m.jd.com/myJd/newhome.action', + 'User-Agent': + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1', + Host: 'me-api.jd.com', + }, + }, + ) + .then((x) => { + console.log(x); + return x.json(); + }) + .then((x) => { + console.log(x.data.userInfo); + if (x.retcode === '0' && x.data && x.data.userInfo) { + return { nickname: x.data.userInfo.baseInfo.nickname, status: 0 }; + } else if (x.retcode === 13) { + return { status: 1, nickname: '-' }; + } + return { status: 2, nickname: '-' }; + }); + } } diff --git a/package.json b/package.json index e9e815d5..aba0699c 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "express": "^4.17.1", "express-basic-auth": "^1.2.0", "express-jwt": "^6.0.0", + "form-data": "^4.0.0", "jsonwebtoken": "^8.5.1", "lodash": "^4.17.20", "mailgun-js": "^0.22.0", diff --git a/src/pages/cookie/index.tsx b/src/pages/cookie/index.tsx index b9f9c427..23a310d6 100644 --- a/src/pages/cookie/index.tsx +++ b/src/pages/cookie/index.tsx @@ -5,27 +5,64 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import QRCode from 'qrcode.react'; +enum Status { + '正常', + '失效', + '状态异常', +} +enum StatusColor { + 'success', + 'error', + 'warning', +} + const columns = [ { title: '用户名', dataIndex: 'pin', key: 'pin', + align: 'center', + render: (text: string, record: any) => { + return {decodeURIComponent(text)}; + }, }, { title: '昵称', dataIndex: 'nickname', key: 'nickname', + align: 'center', }, { title: '值', dataIndex: 'cookie', key: 'cookie', + align: 'center', + render: (text: string, record: any) => { + return ( + + {text} + + ); + }, }, { title: '状态', key: 'status', dataIndex: 'status', - render: (text: string, record: any) => success, + align: 'center', + render: (text: string, record: any) => { + return ( + + {Status[record.status]} + + ); + }, }, { title: '操作', @@ -39,43 +76,19 @@ const columns = [ }, ]; -const data = [ - { - key: '1', - name: 'John Brown', - age: 32, - address: 'New York No. 1 Lake Park', - tags: ['nice', 'developer'], - }, - { - key: '2', - name: 'Jim Green', - age: 42, - address: 'London No. 1 Lake Park', - tags: ['loser'], - }, - { - key: '3', - name: 'Joe Black', - age: 32, - address: 'Sidney No. 1 Lake Park', - tags: ['cool', 'teacher'], - }, -]; - const Config = () => { const [width, setWdith] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); - const [value, setValue] = useState(''); + const [value, setValue] = useState(); const [loading, setLoading] = useState(true); const getConfig = () => { setLoading(true); request - .get(`${config.apiPrefix}config/config`) + .get(`${config.apiPrefix}cookies`) .then((data) => { - setValue(data.content); + setValue(data.data); }) .finally(() => setLoading(false)); }; @@ -128,7 +141,6 @@ const Config = () => { const getCookie = async (modal: { destroy: () => void }) => { for (let i = 0; i < 50; i++) { const result = await request.get(`${config.apiPrefix}cookie`); - console.log(i, result); if (result && result.cookie) { notification.success({ message: 'Cookie获取成功', @@ -164,7 +176,7 @@ const Config = () => { loading={loading} extra={[ , ]} header={{ @@ -186,7 +198,10 @@ const Config = () => { );