You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
308 lines
9.9 KiB
308 lines
9.9 KiB
const {createClient} = require('redis')
|
|
, {RedisJSON, maxClientOnline, user} = require('../config/default.config')
|
|
,{HASH} = require('../tools/user/encryptionString')
|
|
|
|
function initRedisJSON() {
|
|
return new Promise(async (res, rej) => {
|
|
const client = createClient({
|
|
// https://github.com/redis/node-redis
|
|
url: `redis://default:Hxl1314521@${RedisJSON.host}:${RedisJSON.port}`
|
|
});
|
|
try {
|
|
await client.connect()
|
|
RedisJSON.startClear ? client.flushAll() : ''
|
|
client.select(RedisJSON.pool)
|
|
res(client)
|
|
} catch (e) {
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
|
|
const codeList = ['signUp', 'signIn', 'reset', 'writeoff']
|
|
|
|
function Redis() {
|
|
return new Promise(async (res, rej) => {
|
|
try {
|
|
const client = await initRedisJSON()
|
|
|
|
// 初始化RedisJSON池
|
|
// 同类的
|
|
for(let codeType of codeList){
|
|
await client.json.set(codeType, '$', {}, {NX: true});
|
|
}
|
|
// 特殊的
|
|
await client.json.set('login', '$', {}, {NX: true});
|
|
// 执行清理程序
|
|
setInterval(async () => {
|
|
clearAllCode(client)
|
|
}, RedisJSON.clearTime)
|
|
|
|
// 生成对外程序
|
|
const codeMethods = {}
|
|
for(let codeType of codeList){
|
|
const nowCodeType = codeType.replace(codeType[0],codeType.split("")[0].toUpperCase())
|
|
codeMethods['set' + nowCodeType + 'Code'] = (emailOrUsername, code) => setCode(client, codeType, emailOrUsername, code)
|
|
codeMethods['get' + nowCodeType + 'Code'] = (emailOrUsername) => getCode(client, codeType, emailOrUsername)
|
|
codeMethods['del' + nowCodeType + 'Code'] = (emailOrUsername) => delCode(client, codeType, emailOrUsername)
|
|
// codeMethods['clear' + nowCodeType + 'Code'] = () => clearCode(client, codeType)
|
|
}
|
|
const RJ = {
|
|
client,
|
|
// uuid和Token
|
|
setLogin: (uuid, token) => setLogin(client, uuid, token),
|
|
getLogin: (uuid) => getLogin(client, uuid),
|
|
delLogin: (uuid, token) => delLogin(client, uuid, token),
|
|
getToken: (token) => getToken(client, token),
|
|
// 'signUp', 'signIn', 'reset' Code
|
|
...codeMethods
|
|
}
|
|
res(RJ)
|
|
} catch (e) {
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$统一清理程序$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
function clearAllCode(client){
|
|
return new Promise(async (res, rej) => {
|
|
// 清理signUpCOde
|
|
try{
|
|
await clearCode(client, 'signUp')
|
|
}catch (e) {
|
|
console.e('清理注册Code发生异常', e)
|
|
}
|
|
// 清理登录Code
|
|
try{
|
|
await clearCode(client, 'signIn')
|
|
}catch (e) {
|
|
console.e('清理登录Code发生异常', e)
|
|
}
|
|
|
|
// 清理找回密码Code
|
|
try{
|
|
await clearCode(client, 'reset')
|
|
}catch (e) {
|
|
console.e('清理找回密码Code发生异常', e)
|
|
}
|
|
res()
|
|
|
|
// 清理UUID
|
|
try {
|
|
await clearLoginArr(client)
|
|
console.dev('清理UUID成功')
|
|
} catch (e) {
|
|
console.dev('清理UUID发生异常', e)
|
|
}
|
|
|
|
})
|
|
}
|
|
|
|
// ===============================================UUID && Token========================================================
|
|
// login,用于同账号的登陆数量,获取UUID下的TokenList
|
|
function getLogin(client, uuid) {
|
|
return new Promise(async (res, rej) => {
|
|
try {
|
|
const result = await client.json.get('login', {path: uuid})
|
|
res(result)
|
|
} catch (e) {
|
|
if (e.toString().indexOf('not exist') > -1) {
|
|
res([])
|
|
} else {
|
|
rej(e)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
// 添加UUID下的Token
|
|
function setLogin(client, uuid, token) {
|
|
return new Promise(async (res, rej) => {
|
|
try {
|
|
const nowTime = new Date().getTime()
|
|
const result = await getLogin(client, uuid)
|
|
if(result == null){
|
|
console.e('需要重启服务,Redis被清空,没有根节点。')
|
|
throw new Error('需要重启服务,Redis被清空,没有根节点。')
|
|
}
|
|
if (result.length == 0) {
|
|
await client.json.set('login', uuid, [{token, time: nowTime}])
|
|
await setToken(client, token, uuid)
|
|
res()
|
|
} else if (result.length < maxClientOnline) {
|
|
await client.json.ARRAPPEND('login', uuid, {token, time: nowTime})
|
|
await setToken(client, token, uuid)
|
|
res()
|
|
} else {
|
|
// 已经达到最大值了
|
|
for (let i = result.length - 1; i >= 0; i--) {
|
|
if (nowTime - result[i].time > user.login.timeLimit) {
|
|
await delLoginArr(client, uuid, i, result[i].token)
|
|
}
|
|
}
|
|
const result2 = await getLogin(client, uuid)
|
|
if(result2.length == maxClientOnline){
|
|
await delLoginArr(client, uuid, 0, result[0].token)
|
|
}
|
|
await client.json.ARRAPPEND('login', uuid, {token, time: nowTime})
|
|
await setToken(client, token, uuid)
|
|
res()
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
// 删除UUID List中的占用的Token
|
|
function delLoginArr(client, uuid, index, token) {
|
|
return new Promise(async (res, rej) => {
|
|
try {
|
|
await client.json.ARRPOP('login', uuid, index)
|
|
await delToken(client, token)
|
|
res()
|
|
} catch (e) {
|
|
rej(e)
|
|
}
|
|
|
|
})
|
|
}
|
|
// 退出登录时删除UUID下的Token
|
|
function delLogin(client, uuid, token){
|
|
return new Promise(async (res, rej) => {
|
|
try{
|
|
const result = await getLogin(client, uuid)
|
|
for(let i = result.length - 1; i >= 0 ; i--){
|
|
if(result[i].token == token){
|
|
await delLoginArr(client, uuid, i, token)
|
|
}
|
|
}
|
|
res()
|
|
}catch (e) {
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
// 清理过期的UUID下的Token
|
|
function clearLoginArr(client) {
|
|
return new Promise(async (res, rej) => {
|
|
const result = await client.json.get('login')
|
|
const nowTime = new Date().getTime()
|
|
try {
|
|
for (let i in result) {
|
|
const list = result[i];
|
|
for (let j = list.length - 1; j >= 0; j--) {
|
|
if (nowTime - list[j].time > user.login.timeLimit) {
|
|
await delLoginArr(client, i, j, list[j].token)
|
|
}
|
|
}
|
|
}
|
|
res()
|
|
} catch (e) {
|
|
rej(e)
|
|
}
|
|
|
|
})
|
|
}
|
|
// 获取Token的UUID
|
|
function getToken(client, token) {
|
|
return new Promise(async (res, rej) => {
|
|
try {
|
|
const result = await client.get(token)
|
|
res(result)
|
|
} catch (e) {
|
|
if (e.toString().indexOf('not exist') > -1) {
|
|
res([])
|
|
} else {
|
|
rej(e)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
// 添加Token键值对,在添加UUID时,同步添加
|
|
function setToken(client, token, uuid) {
|
|
return new Promise(async (res, rej) => {
|
|
try {
|
|
await client.set(token, uuid)
|
|
res()
|
|
}catch (e) {
|
|
rej()
|
|
}
|
|
})
|
|
}
|
|
// 删除Token键值对,在删除UUID时,同步删除
|
|
function delToken(client, token) {
|
|
return new Promise(async (res, rej) => {
|
|
try{
|
|
const a = await client.del(token)
|
|
if(a != 1){
|
|
rej('删除token指定的UUID失败')
|
|
console.e('删除token指定的UUID失败')
|
|
}else{
|
|
console.dev('删除成功', a)
|
|
}
|
|
res()
|
|
}catch (e) {
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>UUID && Token>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
|
|
// 通用设置Code
|
|
function setCode(client, type, emailOrUsername, code){
|
|
return new Promise(async (res, rej) => {
|
|
try{
|
|
console.log('设置登陆吗')
|
|
// 这里不能设置特殊符号
|
|
emailOrUsername = HASH(emailOrUsername,'md5')
|
|
const time = new Date().getTime()
|
|
const a = await client.json.set(type, emailOrUsername, {code, time}, {NX:true})
|
|
console.log(a)
|
|
res()
|
|
}catch (e) {
|
|
console.log(e)
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
function getCode(client, type, emailOrUsername){
|
|
return new Promise(async (res, rej) => {
|
|
try{
|
|
emailOrUsername = HASH(emailOrUsername,'md5')
|
|
const result = await client.json.get(type, {path: emailOrUsername})
|
|
res(result)
|
|
}catch (e) {
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
function delCode(client, type, emailOrUsername){
|
|
return new Promise(async (res, rej) => {
|
|
try{
|
|
emailOrUsername = HASH(emailOrUsername,'md5')
|
|
const result = await client.json.del(type, emailOrUsername)
|
|
res(result)
|
|
}catch (e) {
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
function clearCode(client, type){
|
|
return new Promise(async (res, rej) => {
|
|
try{
|
|
const nowTime = new Date().getTime()
|
|
const result = await client.json.get(type)
|
|
for(let i in result){
|
|
if(nowTime - result[i].time > RedisJSON.timeout){
|
|
await delResetCode(client, type, i)
|
|
}
|
|
}
|
|
res()
|
|
}catch (e) {
|
|
rej(e)
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
module.exports = Redis |