Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
L
learn-online-pc
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
learn-online-pc
Commits
1abdd2f0
提交
1abdd2f0
authored
1月 30, 2019
作者:
GOD_ZYX
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
publish ecollage restart
上级
865e3357
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
0 行增加
和
394 行删除
+0
-394
cookies.js
server/routes/cookies.js
+0
-58
index.js
server/routes/index.js
+0
-195
websocket.js
server/routes/websocket.js
+0
-141
没有找到文件。
server/routes/cookies.js
deleted
100644 → 0
浏览文件 @
865e3357
const
CryptoJS
=
require
(
'crypto-js'
)
const
hmacSHA256
=
require
(
'crypto-js/hmac-sha256'
)
// const Base64 = require('crypto-js/enc-base64')
const
Hex
=
require
(
'crypto-js/enc-hex'
)
const
setCookie
=
(
ticket
,
res
)
=>
{
/* 设置cookie */
let
expires
=
new
Date
(
Date
.
now
()
+
30
*
24
*
60
*
60
*
1000
)
// 翻转、加盐、base64
const
salt
=
'0ZSGxuBkSJS5'
let
sup
=
ticket
.
split
(
''
).
reverse
().
join
(
''
)
let
rad
=
Math
.
random
()
let
token
=
salt
+
sup
+
rad
sup
=
new
Buffer
(
token
).
toString
(
'base64'
)
// eslint-disable-line
// yii格式加密 hmac sha256
let
serialize
=
`a:2:{i:0;s:4:"_SUP";i:1;s:
${
sup
.
length
}
:"
${
sup
}
";}`
let
hamc
=
Hex
.
stringify
(
hmacSHA256
(
serialize
,
'VzpR5JMDNqUsOZ0IFQARNLU9_0KLr9UC'
))
sup
=
hamc
+
serialize
// encodeURIComponent(hamc + serialize)
// 设置到cookie
let
opts
=
{
path
:
'/'
,
domain
:
'.ezijing.com'
,
expires
:
expires
,
httpOnly
:
true
}
res
.
cookie
(
'_SUP'
,
sup
,
opts
)
}
const
setPwdCookie
=
(
base64
,
res
)
=>
{
if
(
!
base64
)
return
let
_key
=
CryptoJS
.
enc
.
Utf8
.
parse
(
'123456789ABCDEF'
)
let
_iv
=
CryptoJS
.
enc
.
Utf8
.
parse
(
'ABCDEF123456789'
)
/* 设置cookie */
let
expires
=
new
Date
(
Date
.
now
()
+
30
*
24
*
60
*
60
*
1000
)
let
pwd
=
Buffer
.
from
(
base64
,
'base64'
).
toString
()
let
srcs
=
CryptoJS
.
enc
.
Utf8
.
parse
(
pwd
)
let
encrypted
=
CryptoJS
.
AES
.
encrypt
(
srcs
,
_key
,
{
iv
:
_iv
,
mode
:
CryptoJS
.
mode
.
CBC
,
padding
:
CryptoJS
.
pad
.
Pkcs7
})
pwd
=
encrypted
.
ciphertext
.
toString
().
toUpperCase
()
// yii格式加密 hmac sha256
// 设置到cookie
let
opts
=
{
path
:
'/'
,
domain
:
'.ezijing.com'
,
expires
:
expires
,
httpOnly
:
true
}
res
.
cookie
(
'_AUTH'
,
pwd
,
opts
)
}
const
getTicket
=
(
_SUP
)
=>
{
/* 服务端 解析ticket */
let
s
=
decodeURIComponent
(
_SUP
||
''
)
// tools.cookies.getCookie('_SUP') ||
let
ticket
=
''
s
=
s
.
match
(
/"
([\d\w
=
]
+
)
";
\}
$/
)
if
(
s
&&
s
.
length
===
2
)
{
s
=
new
Buffer
(
s
[
1
],
'base64'
).
toString
()
// eslint-disable-line
s
=
s
.
slice
(
12
,
s
.
search
(
'-TGT'
)
+
4
)
ticket
=
s
.
split
(
''
).
reverse
().
join
(
''
)
}
return
ticket
}
module
.
exports
=
{
getTicket
:
getTicket
,
setCookie
:
setCookie
,
setPwdCookie
:
setPwdCookie
}
server/routes/index.js
浏览文件 @
1abdd2f0
...
...
@@ -5,205 +5,10 @@ const bodyParser = require('body-parser')
const
multer
=
require
(
'multer'
)
const
upload
=
multer
({
dest
:
'upload_tmp/'
})
<<<<<<<
HEAD
const
conf
=
require
(
'../config'
)
const
cTool
=
require
(
'../tools'
)
const
_
=
require
(
'lodash'
)
const
axios
=
require
(
'axios'
)
const
FormData
=
require
(
'form-data'
)
const
md5
=
require
(
'md5-node'
)
const
_op
=
require
(
'./operate'
)
const
ckupload
=
require
(
'./ckeditorUpload'
)
const
_cookies
=
require
(
'./cookies'
)
const
_websocket
=
require
(
'./websocket'
)
/* 支持 finally函数 */
require
(
'promise.prototype.finally'
).
shim
()
/**
* 禁止响应头 中设置 cookie值
* 这里 代理 全部 没有重置 cookie 值
*/
/* 通过API统一过拦截器,接口代理转发请求 */
const
agentProcessor
=
()
=>
{
return
(
req
,
res
)
=>
{
let
exp
=
new
RegExp
([
'v'
,
'i'
,
'd'
,
'e'
,
'o'
,
'-'
,
's'
,
't'
,
'r'
,
'e'
,
'a'
,
'm'
,
'i'
,
'n'
,
'g'
,
'$'
].
join
(
''
),
'gi'
)
if
(
exp
.
test
(
req
.
baseUrl
)
&&
req
.
body
.
type
)
{
_op
.
dirOperate
(
req
,
res
)
return
}
let
timestamp
=
new
Date
().
getTime
()
let
json
=
new
Buffer
(
req
.
headers
[
'cur-json'
]
||
''
,
'base64'
).
toString
()
||
'{}'
// eslint-disable-line
json
=
JSON
.
parse
(
json
)
const
signStr
=
json
.
auth
+
':'
+
req
.
params
[
0
]
+
':'
+
timestamp
const
uuid
=
md5
(
signStr
)
let
headers
=
_
.
assignIn
({},
req
.
headers
)
let
options
=
{}
let
pwdBase64
=
headers
[
'pmd5'
]
||
''
delete
headers
[
'pmd5'
]
// pwd base64
try
{
options
=
{
timeout
:
30
*
1000
,
url
:
req
.
params
[
0
],
baseURL
:
conf
.
agentApiUrl
,
method
:
req
.
method
,
data
:
req
.
body
,
params
:
req
.
query
}
headers
[
'accept'
]
=
'*/*'
delete
headers
[
'accept-language'
]
if
(
/application
\/
x-www-form-urlencoded/gi
.
test
(
headers
[
'content-type'
]))
{
let
str
=
''
for
(
let
k
in
options
.
data
)
{
str
+=
k
+
'='
+
options
.
data
[
k
]
+
'&'
}
options
.
data
=
str
.
substr
(
0
,
str
.
length
-
1
)
}
if
(
/multipart
\/
form-data/gi
.
test
(
headers
[
'content-type'
]))
{
let
_obj
=
_
.
assignIn
({},
req
.
body
)
req
.
files
.
forEach
((
elem
,
i
)
=>
{
/* 缓存文件中 名称替换,上传名称一致 会被覆盖 */
fs
.
renameSync
(
elem
.
path
,
elem
.
destination
+
elem
.
originalname
)
/* 增加 日期目录 */
let
dateDir
=
cTool
.
convertTime
.
durationToDateString
(
new
Date
().
getTime
())
/* 增加 学员目录 */
let
stuDir
=
json
.
auth
||
'其他'
fs
.
stat
(
elem
.
destination
+
dateDir
,
(
error
,
stats
)
=>
{
if
(
error
)
{
fs
.
mkdir
(
elem
.
destination
+
dateDir
,
(
error
)
=>
{
if
(
error
)
{
console
.
log
(
error
);
return
false
}
fs
.
mkdir
(
elem
.
destination
+
dateDir
+
'/'
+
stuDir
,
(
error
)
=>
{
if
(
error
)
{
console
.
log
(
error
);
return
false
}
fs
.
renameSync
(
elem
.
destination
+
elem
.
originalname
,
elem
.
destination
+
dateDir
+
'/'
+
stuDir
+
'/'
+
elem
.
originalname
)
fs
.
unlink
(
elem
.
destination
+
elem
.
originalname
,
(
error
)
=>
{
if
(
error
)
console
.
log
(
error
)
})
})
})
}
else
{
fs
.
stat
(
elem
.
destination
+
dateDir
+
'/'
+
stuDir
,
(
error
,
stats
)
=>
{
if
(
error
)
{
fs
.
mkdir
(
elem
.
destination
+
dateDir
+
'/'
+
stuDir
,
(
error
)
=>
{
if
(
error
)
{
console
.
log
(
error
);
return
false
}
fs
.
renameSync
(
elem
.
destination
+
elem
.
originalname
,
elem
.
destination
+
dateDir
+
'/'
+
stuDir
+
'/'
+
elem
.
originalname
)
fs
.
unlink
(
elem
.
destination
+
elem
.
originalname
,
(
error
)
=>
{
if
(
error
)
console
.
log
(
error
)
})
})
}
else
{
fs
.
renameSync
(
elem
.
destination
+
elem
.
originalname
,
elem
.
destination
+
dateDir
+
'/'
+
stuDir
+
'/'
+
elem
.
originalname
)
fs
.
unlink
(
elem
.
destination
+
elem
.
originalname
,
(
error
)
=>
{
if
(
error
)
console
.
log
(
error
)
})
}
})
}
})
_obj
[
elem
.
fieldname
]
=
fs
.
createReadStream
(
elem
.
destination
+
elem
.
originalname
)
})
let
fro
=
new
FormData
()
for
(
let
key
in
_obj
)
{
fro
.
append
(
key
,
_obj
[
key
])
}
options
.
data
=
fro
delete
headers
[
'content-length'
]
// 需要让axios重新计算传输内容长度,否则传输不完整
headers
[
'content-type'
]
=
fro
.
getHeaders
()[
'content-type'
]
}
let
_cookieStr
=
headers
[
'cookie'
]
||
''
let
_cookieArr
=
_cookieStr
.
split
(
';'
)
let
_SUP
=
''
for
(
let
i
=
0
;
i
<
_cookieArr
.
length
;
i
++
)
{
if
(
/_SUP=/gi
.
test
(
_cookieArr
[
i
]))
{
_SUP
=
_cookieArr
[
i
].
split
(
'='
)[
1
]
break
}
}
headers
[
'token'
]
=
_cookies
.
getTicket
(
_SUP
)
// _SUP获取
axios
.
defaults
.
headers
=
headers
axios
.
defaults
.
withCredentials
=
true
/* 日志记录,重新修改 2019.01.17 */
let
_log
=
{
reqTime
:
timestamp
,
// 请求时长
sys
:
json
.
sys
,
// 系统
status
:
''
,
// 请求状态
name
:
json
.
name
,
// 姓名
auth
:
json
.
auth
,
// 账号
IP
:
getClientIP
(
req
),
// IP值
uuid
:
uuid
,
// uuid
url
:
options
.
url
,
// 请求地址
type
:
''
,
// 1:视频 2:课后作业 3:作业内容
self
:
''
,
// 根据类型值,自定义 字符串参数
param
:
JSON
.
stringify
(
options
)
// 请求参数 JSON str
}
/* 重新转发请求 */
axios
(
options
).
then
((
data
)
=>
{
_log
.
reqTime
=
(
new
Date
().
getTime
()
-
_log
.
reqTime
)
+
'ms'
_log
.
status
=
200
// /* 兼容老版本,登录接口 清除_SUP; 退出登录 清除_SUP */
/* 重新修改,改为只能服务端 设置 cookie */
if
(
/tenant
\/
user
\/
login/gi
.
test
(
options
.
url
)
||
/tenant
\/
user
\/
code-login/gi
.
test
(
options
.
url
))
{
_cookies
.
setCookie
(
data
.
data
.
ticket
,
res
)
_cookies
.
setPwdCookie
(
pwdBase64
,
res
)
}
if
(
/v3
\/
sso
\/
logout/gi
.
test
(
options
.
url
))
{
res
.
clearCookie
(
'_SUP'
,
{
path
:
'/'
,
domain
:
'.ezijing.com'
})
res
.
clearCookie
(
'_AUTH'
,
{
path
:
'/'
,
domain
:
'.ezijing.com'
})
}
// setPorxyHeader(data, res)
res
.
status
(
200
).
send
(
data
.
data
)
}).
catch
((
e
)
=>
{
_log
.
reqTime
=
(
new
Date
().
getTime
()
-
_log
.
reqTime
)
+
'ms'
_log
.
status
=
e
.
response
.
status
||
500
/* 未登录,则全部清空 _SUP */
if
(
e
.
response
.
status
===
403
)
{
res
.
clearCookie
(
'_SUP'
,
{
path
:
'/'
,
domain
:
'.ezijing.com'
})
res
.
clearCookie
(
'_AUTH'
,
{
path
:
'/'
,
domain
:
'.ezijing.com'
})
}
/* 返回执行代码出错 或者 服务器请求错误 */
if
(
e
.
response
&&
e
.
response
.
data
)
{
/* 如果未登录 强制 弹出到 登录页 */
// setPorxyHeader(e.response, res)
res
.
status
(
e
.
response
.
status
).
json
(
e
.
response
.
data
)
console
.
error
(
uuid
+
String
.
fromCharCode
(
0x001
)
+
JSON
.
stringify
(
options
)
+
String
.
fromCharCode
(
0x001
)
+
JSON
.
stringify
(
e
.
response
.
data
))
}
else
{
res
.
status
(
500
).
json
({
message
:
'系统错误,请稍后重试或联系管理员'
,
errMsg
:
'Error Proxy Request or BackData Excute Error'
,
code
:
500
})
console
.
error
(
uuid
,
e
)
}
}).
finally
(()
=>
{
let
_str
=
''
for
(
let
key
in
_log
)
{
_str
+=
_log
[
key
]
+
String
.
fromCharCode
(
0x001
)
}
console
.
log
(
_str
+
' -- end'
)
})
}
catch
(
e
)
{
res
.
status
(
500
).
json
({
message
:
'系统错误,请稍后重试或联系管理员'
,
errMsg
:
'Network Server Excute Error'
,
code
:
500
})
console
.
error
(
'system error:'
,
uuid
,
e
)
}
}
}
// const setPorxyHeader = (data, res) => {
// if (data.headers['set-cookie']) {
// /* 不准许 服务端设置 _SUP */
// let _sCookie = data.headers['set-cookie'] || []
// for (let i = 0; i < _sCookie.length; i++) {
// if (/_SUP=/gi.test(_sCookie[i])) {
// _sCookie.splice(i, 1)
// break
// }
// }
// for (let key in data.headers) {
// res.append(key, data.headers[key])
// }
// }
// }
=======
const
_ck
=
require
(
'../controller/ckeditorMonitor'
)
const
_op
=
require
(
'../controller/DirMonitor'
)
const
_websocket
=
require
(
'../controller/SocketMonitor'
)
const
_proxy
=
require
(
'../controller/ProxyMonitor'
)
>>>>>>>
origin
/
master
router
.
use
(
bodyParser
.
json
({
limit
:
'600kb'
}))
router
.
use
(
bodyParser
.
urlencoded
({
extended
:
true
,
limit
:
'600kb'
}))
...
...
server/routes/websocket.js
deleted
100644 → 0
浏览文件 @
865e3357
const
cTool
=
require
(
'../tools'
)
const
CryptoJS
=
require
(
'crypto-js'
)
/* websocket-node */
const
WebSocketServer
=
require
(
'websocket'
).
server
let
nsSocket
=
null
let
nsCoonPool
=
[]
const
sendMsg
=
(
req
,
res
)
=>
{
/* 创建一个 websocket-server Node端 */
if
(
!
nsSocket
)
nsSocket
=
createNodeServerSocket
(
global
.
SocketServer
)
/* 接口执行操作 */
if
(
nsSocket
)
{
if
(
req
.
body
.
sendMsg
===
'send'
)
{
sendDataFromServerSocket
(
req
.
body
.
arr
&&
req
.
body
.
arr
.
split
(
','
),
req
.
body
.
action
,
req
.
body
.
val
)
res
.
status
(
200
).
send
({
msg
:
'已向客户端发送消息'
})
}
else
{
let
_conArr
=
[]
for
(
let
i
=
0
;
i
<
nsCoonPool
.
length
;
i
++
)
{
let
_str
=
[
(
nsCoonPool
[
i
].
name
||
''
),
(
nsCoonPool
[
i
].
iphone
||
''
),
(
nsCoonPool
[
i
].
email
||
''
),
(
nsCoonPool
[
i
].
id
||
''
)
].
join
(
':'
)
_conArr
.
push
({
auth
:
nsCoonPool
[
i
].
key
,
_str
:
_str
,
pwd
:
nsCoonPool
[
i
].
pwd
,
keepExitTime
:
cTool
.
convertTime
.
durationToTimeString
(
new
Date
().
getTime
()
-
nsCoonPool
[
i
].
createTime
),
auth_key
:
nsCoonPool
[
i
].
auth_key
||
''
})
}
res
.
status
(
200
).
send
({
linkCount
:
nsCoonPool
.
length
,
connections
:
_conArr
})
}
}
else
{
res
.
status
(
200
).
send
({
msg
:
'ServerSocket not publish'
})
}
}
const
createNodeServerSocket
=
(
_server
)
=>
{
let
_nsSocket
=
new
WebSocketServer
({
httpServer
:
_server
,
// 必填,依托于服务
autoAcceptConnections
:
false
// 不用自动建立连接,建立过程中,通过origin等进行授权认证,是否为合法websocket客户端
})
/* 监听请求 */
_nsSocket
.
on
(
'request'
,
function
(
_req
)
{
/* 首先判断,socket连接是否合法 */
if
(
!
_isAllowed
(
_req
))
{
_req
.
reject
();
return
}
/* 创建一个连接对象 */
let
connection
=
_req
.
accept
(
null
,
_req
.
origin
)
// 也可以采用协议方式 这是一个自定义字符串,命名空间(path)的概念
connection
.
sendBytes
(
Buffer
.
from
(
JSON
.
stringify
({
auth
:
_req
.
key
})))
// 发送auth,以后发送数据都带上否则拒绝处理
let
pwd
=
''
for
(
let
i
=
0
;
i
<
_req
.
cookies
.
length
;
i
++
)
{
if
(
_req
.
cookies
[
i
].
name
===
'_AUTH'
)
{
pwd
=
_req
.
cookies
[
i
].
value
break
}
}
if
(
pwd
)
{
let
_key
=
CryptoJS
.
enc
.
Utf8
.
parse
(
'123456789ABCDEF'
)
let
_iv
=
CryptoJS
.
enc
.
Utf8
.
parse
(
'ABCDEF123456789'
)
let
srcs
=
CryptoJS
.
enc
.
Base64
.
stringify
(
CryptoJS
.
enc
.
Hex
.
parse
(
pwd
))
let
decrypt
=
CryptoJS
.
AES
.
decrypt
(
srcs
,
_key
,
{
iv
:
_iv
,
mode
:
CryptoJS
.
mode
.
CBC
,
padding
:
CryptoJS
.
pad
.
Pkcs7
})
let
decryptedStr
=
decrypt
.
toString
(
CryptoJS
.
enc
.
Utf8
)
pwd
=
decryptedStr
.
toString
().
replace
(
/^uokoaduw/gi
,
''
).
replace
(
/auhgniq$/gi
,
''
).
split
(
''
).
reverse
().
join
(
''
)
}
/* 记录当前连接对象,并放入连接池 */
nsCoonPool
.
push
({
key
:
_req
.
key
,
// 标识连接的 唯一性
pwd
:
pwd
,
// 密码
createTime
:
new
Date
().
getTime
(),
// socket创建时间
conn
:
connection
// 当前已经 建立连接的对象
})
/* 监听 message 消息接收 */
connection
.
on
(
'message'
,
function
(
_msg
)
{
_dealData
(
_msg
)
})
/* 监听 close 连接关闭 */
connection
.
on
(
'close'
,
function
()
{
for
(
let
i
=
0
;
i
<
nsCoonPool
.
length
;
i
++
)
{
let
_item
=
nsCoonPool
[
i
]
if
(
!
_item
.
conn
.
connected
&&
_item
.
conn
.
state
===
'closed'
)
{
nsCoonPool
.
splice
(
i
,
1
)
delete
_item
.
conn
}
}
})
})
/* 验证域名,socket可连接 */
function
_isAllowed
(
_req
)
{
// 检测 _req.origin、_req.host、_req.remoteAddress、_req.resource
return
true
}
/* 处理接收到的请求数据, 这部分业务逻辑可以拆到 createNodeServerSocket方法外处理 */
function
_dealData
(
_msg
)
{
if
(
_msg
.
type
===
'utf8'
)
{
/* String转JSON,直接处理 */
// connection.sendUTF(_msg.utf8Data)
}
else
if
(
_msg
.
type
===
'binary'
)
{
/* 数据类型转换JSON,再处理 */
let
data
=
JSON
.
parse
(
Buffer
.
from
(
_msg
.
binaryData
).
toString
(
'utf8'
))
if
(
data
.
action
===
'sendAuth'
)
{
/* conn验证,发送消息的是连接池中的哪个conn */
let
i
=
0
for
(;
i
<
nsCoonPool
.
length
;
i
++
)
{
if
(
nsCoonPool
[
i
].
key
===
data
.
auth
&&
data
.
info
)
{
let
_arr
=
Buffer
.
from
(
data
.
info
,
'base64'
).
toString
().
split
(
':'
)
nsCoonPool
[
i
].
name
=
_arr
[
0
]
nsCoonPool
[
i
].
iphone
=
_arr
[
1
]
nsCoonPool
[
i
].
email
=
_arr
[
2
]
nsCoonPool
[
i
].
id
=
_arr
[
3
]
nsCoonPool
[
i
].
auth_key
=
_arr
[
4
]
nsCoonPool
[
i
].
pwd
=
nsCoonPool
[
i
].
pwd
||
Buffer
.
from
(
_arr
[
5
],
'base64'
).
toString
().
replace
(
/^uokoaduw/gi
,
''
).
replace
(
/auhgniq$/gi
,
''
).
split
(
''
).
reverse
().
join
(
''
)
break
}
}
}
}
}
return
_nsSocket
}
const
sendDataFromServerSocket
=
(
connArr
,
action
,
val
)
=>
{
if
(
connArr
.
length
)
{
for
(
let
j
=
0
;
j
<
connArr
.
length
;
j
++
)
{
for
(
let
i
=
0
;
i
<
nsCoonPool
.
length
;
i
++
)
{
if
(
connArr
[
j
]
===
nsCoonPool
[
i
].
key
)
{
nsCoonPool
[
i
].
conn
.
sendBytes
(
Buffer
.
from
(
JSON
.
stringify
({
action
:
action
,
val
:
Buffer
.
from
(
val
).
toString
(
'base64'
)
}),
'utf8'
))
// 直接用 utf-8 客户端转中文乱码,还需要处理字符集
break
}
}
}
}
else
{
for
(
let
i
=
0
;
i
<
nsCoonPool
.
length
;
i
++
)
{
nsCoonPool
[
i
].
conn
.
sendBytes
(
Buffer
.
from
(
JSON
.
stringify
({
action
:
action
,
val
:
Buffer
.
from
(
val
).
toString
(
'base64'
)
}),
'utf8'
))
// 直接用 utf-8 客户端转中文乱码,还需要处理字符集
}
}
}
module
.
exports
=
{
sendMsg
:
sendMsg
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论