@@ -14,12 +14,29 @@ module.exports = app => {
14
14
15
15
constructor ( ctx ) {
16
16
super ( ctx )
17
- this . url = 'https://www.v2ex.com/signin'
18
- this . setCookiestr = '' // 供放在headers里使用
19
- this . cookies = '' // get到的cookie暂存,供合并给最终的cookies
20
- this . userKey = ''
21
- this . passKey = ''
22
- this . once = ''
17
+ this . commonHeaders = {
18
+ "Accept" : "text/html,application/xhtml+xml,application/xml" ,
19
+ "Origin" : "https://www.v2ex.com" ,
20
+ "Referer" : "https://www.v2ex.com/massion" ,
21
+ "User-Agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
22
+ }
23
+
24
+ // sessionid
25
+ this . sessionCookieName = 'PB3_SESSION'
26
+
27
+ // token cookie name
28
+ this . tokenCookieName = 'A2'
29
+
30
+ // 获取登陆签名
31
+ this . loginUrl = 'https://www.v2ex.com/signin'
32
+ this . sessionCookie = '' // 供 `login`接口放在Header里 `Set-Cookie` 使用
33
+ this . loginCookieArr = '' // get到的cookie暂存,供合并给最终的cookie
34
+ this . userKey = '' // 用户名 输入框埋下的随机key
35
+ this . passKey = '' // 密码 输入框埋下的随机key
36
+ this . once = '' // input[type="hidden"][name="once"]的随机令牌值(5位数字目前)
37
+
38
+ // 签到领金币
39
+ this . signinUrl = 'https://www.v2ex.com/mission/daily'
23
40
}
24
41
25
42
async request ( url , opts ) {
@@ -30,7 +47,7 @@ module.exports = app => {
30
47
return await this . ctx . curl ( url , opts )
31
48
}
32
49
33
- getKeys ( content ) {
50
+ getLoginTokens ( content ) {
34
51
const re = / c l a s s = " s l " \s * n a m e = \" ( \w * ) / g
35
52
const onceRe = / t y p e = " h i d d e n " \s * v a l u e = " ( \w * ) \s * /
36
53
const matches = content && content . match ( re )
@@ -39,71 +56,120 @@ module.exports = app => {
39
56
this . once = content . match ( onceRe ) [ 1 ]
40
57
}
41
58
42
- async getAuthPrepare ( ) {
43
- const result = await this . request ( this . url , {
59
+ /**
60
+ * getLoginPrepare
61
+ *
62
+ */
63
+ async getLoginPrepare ( ) {
64
+ const result = await this . request ( this . loginUrl , {
44
65
method : 'GET' ,
45
66
dataType : 'text' ,
46
- headers : {
47
- "accept" : "text/html,application/xhtml+xml,application/xml" ,
48
- "origin" : "https://www.v2ex.com" ,
49
- "referer" : "https://www.v2ex.com/signin" ,
50
- "user-agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
51
- }
67
+ headers : this . commonHeaders
52
68
} )
53
- this . setCookiestr = result . headers [ 'set-cookie' ] [ 0 ]
69
+
70
+ this . sessionCookie = result . headers [ 'set-cookie' ] [ 0 ]
71
+
54
72
const cs = setCookieParser ( result )
55
- this . cookies = cs
56
73
57
- // set cookies for client
58
- cs . forEach ( c => {
59
- this . ctx . cookies . set ( c . name , c . value , {
60
- domain : '' ,
61
- expires : c . expires ,
62
- path : c . path ,
63
- httpOnly : c . httpOnly
64
- } )
65
- } )
66
- return this . getKeys ( result . data )
74
+ // 设置到暂存对象中
75
+ this . loginCookieArr = cs . filter ( cookie => cookie . name !== 'V2EX_LANG' )
76
+
77
+ return this . getLoginTokens ( result . data )
67
78
}
68
79
69
- async signin ( ctx ) {
80
+ /**
81
+ * login
82
+ * 登陆获取签名
83
+ *
84
+ * @param params
85
+ */
86
+ async login ( params ) {
70
87
71
- await this . getAuthPrepare ( )
88
+ await this . getLoginPrepare ( )
89
+
90
+ const { username, password } = params
72
91
73
92
const opts = {
74
93
method : 'POST' ,
75
- headers : {
76
- "method" : "POST" ,
77
- "accept" : "text/html,application/xhtml+xml,application/xml" ,
78
- "origin" : "https://www.v2ex.com" ,
79
- "referer" : "https://www.v2ex.com/signin" ,
80
- "Cookie" : this . setCookiestr ,
81
- "user-agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
82
- } ,
94
+ headers : Object . assign ( this . commonHeaders , { Cookie : this . sessionCookie } ) ,
83
95
data : {
84
- [ this . userKey ] : "your username" ,
85
- [ this . passKey ] : "your password" ,
86
- "once" : this . once ,
87
- "next" : "/"
96
+ [ this . userKey ] : username ,
97
+ [ this . passKey ] : password ,
98
+ "once" : this . once
88
99
}
89
100
}
90
101
91
- const result = await this . request ( this . url , opts )
102
+ const result = await this . request ( this . loginUrl , opts )
92
103
93
104
const cs = setCookieParser ( result )
94
- // set cookies for client
95
- cs . forEach ( c => {
105
+ const tokens = cs . concat ( this . loginCookieArr )
106
+ let success = false
107
+ tokens . forEach ( c => {
108
+ if ( c . name === this . tokenCookieName ) success = true
96
109
this . ctx . cookies . set ( c . name , c . value , {
110
+ httpOnly : true ,
97
111
domain : '' ,
98
112
path : c . path ,
99
- expires : c . expires ,
100
- httpOnly : c . httpOnly
113
+ expires : c . expires
101
114
} )
102
115
} )
103
116
104
- // return all cookies to client
105
- return cs . concat ( this . cookies . filter ( item => item . name === 'PB3_SESSION' ) )
117
+ return {
118
+ result : success ,
119
+ msg : success ? 'success' : 'sorry! Not get enough token for you' ,
120
+ data : {
121
+ username : username
122
+ }
123
+ }
124
+ }
125
+
126
+ getSigninOnce ( content ) {
127
+ // update this.once
128
+ const onceResult = content . match ( / o n c e = ( \w * ) / g) [ 1 ]
129
+ this . once = onceResult . match ( / o n c e = ( \w * ) / ) [ 1 ]
130
+ }
131
+
132
+ async getSigninPrepare ( ) {
133
+ const token = `A2=${ this . ctx . cookies . get ( 'A2' ) } `
134
+ const result = await this . request ( this . signinUrl , {
135
+ method : 'GET' ,
136
+ dataType : 'text' ,
137
+ headers : Object . assign ( this . commonHeaders , { Cookie : `${ this . sessionCookie } ${ token } ` } )
138
+ } )
139
+
140
+ return this . getSigninOnce ( result . data )
141
+ }
142
+
143
+ /**
144
+ * signin
145
+ * 签到领金币
146
+ *
147
+ * @param params
148
+ */
149
+ async signin ( params ) {
150
+ await this . getSigninPrepare ( )
151
+
152
+ const token = `${ this . tokenCookieName } =${ this . ctx . cookies . get ( this . tokenCookieName ) } `
153
+ const session = `${ this . sessionCookieName } =${ this . ctx . cookies . get ( this . sessionCookieName ) } `
154
+ const headers = Object . assign ( this . commonHeaders , { Cookie : `${ session } ; ${ token } ` } )
155
+ console . log ( headers , this . once )
156
+ const opts = {
157
+ dataType : 'text' ,
158
+ method : 'get'
159
+ }
160
+
161
+ const result = await this . request ( `${ this . signinUrl } /redeem` , Object . assign ( opts , {
162
+ headers : headers ,
163
+ data : {
164
+ 'once' : this . once
165
+ }
166
+ } ) )
167
+ const success = await this . request ( `${ this . signinUrl } ` , Object . assign ( opts , {
168
+ headers : this . commonHeaders
169
+ } ) )
170
+ return success
106
171
}
107
172
108
173
} // /.class=>AuthService
109
174
}
175
+
0 commit comments