Skip to content

Commit 2cc49cc

Browse files
committed
opt code
1 parent 3eeb124 commit 2cc49cc

File tree

2 files changed

+67
-79
lines changed

2 files changed

+67
-79
lines changed

app/middleware/error_handler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = app => {
1919
// 生产环境 500 错误的详细错误内容不返回给客户端,因为可能包含敏感信息
2020
const error = status === 500 && ctx.app.config.env === 'prod'
2121
? 'Internal Server Error'
22-
: `from: middleware, msg: ${err.message}, stacks ${err.stack}`
22+
: `catchBy: middleware, msg: ${err.message}, stacks ${err.stack}`
2323
// 从 error 对象上读出各个属性,设置到响应中
2424
ctx.body = { error }
2525
// 422 Unprocessable Entity

app/service/auth.js

Lines changed: 66 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Date : Tue 14 Mar 2017 03:19:07 PM CST
88
*/
99

10+
// import parser
1011
const setCookieParser = require('set-cookie-parser')
1112

1213
module.exports = app => {
@@ -15,38 +16,38 @@ module.exports = app => {
1516
/**
1617
* @constructor
1718
*
18-
* @param ctx
19+
* @param {Objet} ctx - context object
1920
*/
2021
constructor (ctx) {
2122
super(ctx)
23+
2224
this.commonHeaders = {
2325
"Accept": "text/html,application/xhtml+xml,application/xml",
2426
"Origin": "https://www.v2ex.com",
25-
"Referer": "https://www.v2ex.com/mission/daily",
27+
"Referer": "https://www.v2ex.com",
2628
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
2729
}
2830

2931
this.commonCookies = {
3032
tab: 'V2EX_TAB="2|1:0|10:1489746039|8:V2EX_TAB|8:dGVjaA==|b72b63fabe0f8faeff147ac38e26299655d713ad1880feef6679b56d8d1e9f47"',
31-
lang: 'V2EX_LANG=zhcn; _ga=GA1.2.1254455933.1474272858; _gat=1'
33+
others: 'V2EX_LANG=zhcn; _ga=GA1.2.1254455933.1474272858; _gat=1'
3234
}
3335

34-
// sessionid
36+
// sessionid cookie name
3537
this.sessionCookieName = 'PB3_SESSION'
3638

37-
// token cookie name
39+
// token cookie name
3840
this.tokenCookieName = 'A2'
3941

4042
// 首页url
4143
this.homeUrl = 'https://www.v2ex.com/'
4244

43-
// 获取登陆签名
45+
// 登陆相关
4446
this.loginUrl = 'https://www.v2ex.com/signin'
45-
this.sessionCookie = '' // 供 `login`接口放在Header里 `Set-Cookie` 使用
46-
// this.loginCookieArr = '' // get到的cookie暂存,供合并给最终的cookie
47-
this.userKey = '' // 用户名 输入框埋下的随机key
48-
this.passKey = '' // 密码 输入框埋下的随机key
49-
this.once = '' // input[type="hidden"][name="once"]的随机令牌值(5位数字目前)
47+
this.sessionCookieStr = '' // 未登陆的sessionid, 供 `login` 接口放在请求Headers里的 `Set-Cookie` 项中使用
48+
this.userField = '' // 用户名 输入框埋下的随机表单域
49+
this.passField = '' // 密码 输入框埋下的随机表单域
50+
this.once = '' // input[type="hidden"][name="once"]的随机令牌值(目前是5位数字)
5051

5152
// 签到领金币url
5253
this.signinUrl = 'https://www.v2ex.com/mission/daily'
@@ -56,8 +57,8 @@ module.exports = app => {
5657
* request
5758
* 封装统一的请求方法
5859
*
59-
* @param url
60-
* @param opts
60+
* @param {String} url - 请求地址
61+
* @param {Object} opts - 请求选项
6162
* @returns {Promise}
6263
*/
6364
async request (url, opts) {
@@ -75,14 +76,10 @@ module.exports = app => {
7576
* @returns {Promise}
7677
*/
7778
async enterHomePage () {
78-
const result = await this.request(this.homeUrl, {
79-
method: 'GET',
80-
dataType: 'text',
81-
headers: this.commonHeaders
82-
})
79+
const result = await this.request(this.homeUrl)
8380

84-
const cs = setCookieParser(result)
85-
cs.forEach(c => {
81+
const session = setCookieParser(result)
82+
session.forEach(c => {
8683
this.ctx.cookies.set(c.name, c.value, {
8784
httpOnly: c.httpOnly,
8885
domain: '',
@@ -93,23 +90,28 @@ module.exports = app => {
9390
}
9491

9592
/**
96-
* getLoginKeys
93+
* getLoginFields
9794
* 获取登陆的各种凭证
9895
*
99-
* @param content
96+
* @param {String} result - 请求登陆页返回的response,包含html字符串和Headers
10097
*/
101-
getLoginKeys (content) {
102-
var keyRe = /class="sl" name="([0-9A-Za-z]{64})"/g
103-
this.userKey = keyRe.exec(content)[1]
104-
this.passKey = keyRe.exec(content)[1]
105-
var onceRe = /value="(\d+)" name="once"/
98+
getLoginFields (result) {
99+
const content = result.data
100+
101+
const keyRe = /class="sl" name="([0-9A-Za-z]{64})"/g
102+
this.userField = keyRe.exec(content)[1]
103+
this.passField = keyRe.exec(content)[1]
104+
105+
const onceRe = /value="(\d+)" name="once"/
106106
this.once = onceRe.exec(content)[1]
107+
108+
this.sessionCookieStr = result.headers['set-cookie'][0]
107109
}
108110

109111
/**
110112
* enterLoginPage
111113
* login前的准备
112-
* 获取sessionid,获取userKey, passKey, once等
114+
* 获取sessionid,获取userField, passField, once等
113115
*
114116
* @returns {Promise}
115117
*/
@@ -120,61 +122,47 @@ module.exports = app => {
120122
headers: this.commonHeaders
121123
})
122124

123-
// 供发起login的header里使用
124-
this.sessionCookie = result.headers['set-cookie'][0]
125-
console.log('================================before login', this.sessionCookie)
126-
127-
const cs = setCookieParser(result)
128-
129-
return this.getLoginKeys(result.data)
125+
return this.getLoginFields(result)
130126
}
131127

132128
/**
133129
* login
134130
* login获取签名主方法
135131
*
136-
* @param params
132+
* @param {Object} params - 请求参数
137133
*/
138134
async login (params) {
139135

140-
// @step1: 获取提交的用户名密码
136+
// @step1 获取提交的用户名密码
141137
const { username, password } = params
142138

143-
// 进入登陆页,获取页面隐藏登陆域以及once的值
139+
// @step2 进入登陆页,获取页面隐藏登陆域以及once的值
144140
await this.enterLoginPage()
145141

146-
// 设置请求选项
142+
// @step3 设置请求参数
147143
const opts = {
148144
method: 'POST',
149-
headers: Object.assign(this.commonHeaders, { Cookie: this.sessionCookie }),
145+
headers: Object.assign(this.commonHeaders, { Cookie: this.sessionCookieStr }),
150146
data: {
151-
[this.userKey]: username,
152-
[this.passKey]: password,
147+
[this.userField]: username,
148+
[this.passField]: password,
153149
"once": this.once
154150
}
155151
}
156152

157-
// 发起请求
153+
// @step4 发起请求
158154
const result = await this.request(this.loginUrl, opts)
159155

160-
// 获取cookies
156+
// @step5 更新session并设置在客户端
157+
await this.enterHomePage()
158+
159+
// @step6 解析获取到的cookies
161160
const cs = setCookieParser(result)
162161

163-
// 更新session并设置在客户端
164-
const r = this.request(this.homeUrl)
165-
const session = setCookieParser(r)
166-
session.forEach(c => {
167-
this.ctx.cookies.set(c.name, c.value, {
168-
httpOnly: c.httpOnly,
169-
domain: '',
170-
path: c.path,
171-
expires: c.expires
172-
})
173-
})
174-
175-
// 判断是否登陆成功并设置客户端cookies
162+
// @step7 判断是否登陆成功并种下客户端cookies
176163
let success = false
177164
cs.forEach(c => {
165+
// 查看是否有令牌项的cookie,有就说明登陆成功了
178166
if (c.name === this.tokenCookieName) success = true
179167
this.ctx.cookies.set(c.name, c.value, {
180168
httpOnly: c.httpOnly,
@@ -187,7 +175,7 @@ module.exports = app => {
187175
// 设置API返回结果
188176
return {
189177
result: success,
190-
msg: success ? 'success' : 'sorry! Not get enough token for you',
178+
msg: success ? 'ok' : 'sorry! Not get enough `Token`...',
191179
data: {
192180
username: username
193181
}
@@ -198,14 +186,13 @@ module.exports = app => {
198186
* getSigninOnce
199187
* 获取签到的once值
200188
*
201-
* @param content
189+
* @param {String} content - 签到页html字符串
202190
*/
203191
getSigninOnce (content) {
204-
// update this.once
205192
try {
206-
const onceResult = content.match(/once=(\w*)/g)[1]
207-
this.once = onceResult.match(/once=(\w*)/)[1]
208-
console.log('once------------------------', this.once)
193+
// update this.once
194+
const onceRe = /redeem\?once=(\d+)/
195+
this.once = onceRe.exec(content)[1]
209196
} catch (e) {
210197
throw new Error('已经签到过了')
211198
}
@@ -215,57 +202,58 @@ module.exports = app => {
215202
* enterSigninPage
216203
* 进入签到页面,获取once值
217204
*
218-
* @returns {undefined}
219205
*/
220206
async enterSigninPage () {
221-
await this.enterHomePage()
222207

223208
const token = `${this.tokenCookieName}=${this.ctx.cookies.get(this.tokenCookieName)}`
224209
const session = `${this.sessionCookieName}=${this.ctx.cookies.get(this.sessionCookieName)}`
225210
const headers = Object.assign(this.commonHeaders, { Cookie: `${session}; ${token}` })
211+
226212
const result = await this.request(this.signinUrl, {
227213
method: 'GET',
228214
dataType: 'text',
229215
headers: headers
230216
})
231217

232-
return this.getSigninOnce(result.data)
218+
this.getSigninOnce(result.data)
219+
return
233220
}
234221

235222
/**
236223
* signin
237224
* 签到领金币
238-
*
239-
* @param params
240225
*/
241-
async signin (params) {
242-
// 进入签到页面
226+
async signin () {
227+
228+
// @step1 进入签到页面
243229
await this.enterSigninPage()
244230

245-
// 获取客户端凭证和cookie
246-
const { tab, lang } = this.commonCookies
231+
// @step2 获取客户端凭证和各种cookies
247232
const session = `${this.sessionCookieName}=${this.ctx.cookies.get(this.sessionCookieName)}`
248233
const token = `${this.tokenCookieName}=${this.ctx.cookies.get(this.tokenCookieName)}`
234+
const { tab, others } = this.commonCookies
249235

250-
// 设置header
251-
const headers = Object.assign(this.commonHeaders, { Cookie: `${session}; ${token}; ${tab}; ${lang};` })
252-
console.log('headers: -------------------------------', headers)
236+
// @step3 设置Headers
237+
const headers = Object.assign(this.commonHeaders,
238+
{ Referer: 'https://www.v2ex.com/mission/daily' },
239+
{ Cookie: `${session}; ${token}; ${tab}; ${others};` }
240+
)
253241

254-
// 设置请求选项
242+
// @step4 设置请求选项
255243
const opts = {
256244
dataType: 'text',
257245
method: 'get'
258246
}
259247

260-
// 获取请求结果,会302
248+
// @step5 获取请求结果,会302
261249
const result = await this.request(`${this.signinUrl}/redeem`, Object.assign(opts, {
262250
headers: headers,
263251
data: {
264252
'once': this.once
265253
}
266254
}))
267255

268-
// 重新进入签到页面,确认是否签到成功
256+
// @step6 重新进入签到页面,确认是否签到成功
269257
const success = await this.request(`${this.signinUrl}`, Object.assign(opts, {
270258
headers: this.commonHeaders
271259
}))

0 commit comments

Comments
 (0)