'use strict'; const Controller = require('../core/base_controller'); const fileName = "verify"; const redisType = { "B": "db0", "C": "db1", "M": "db2", "T": "db5", "E": "db6", "A": "db7" }; const modelType = { "B": "bSide", "C": "cSide", "M": "insiders", "T": "contest", "E": "exam", "A": "examManager" }; const checkUid = async (thisPlace) => { const ctx = thisPlace.ctx; const uid = ctx.request.body.uid; const token = ctx.request.header.authorization; const redis = ctx.app.redis; let rdmcode; if (!uid) { let allRedis = []; Object.entries(redisType).forEach(([key, value]) => { allRedis.push(redis.get(value).get(token)); }); const [buser, cuser, muser, tuser, euser, auser] = await Promise.all(allRedis); rdmcode = buser || cuser || muser || tuser || euser || auser; } else { let decryptUid = thisPlace.decryptRequest(uid).split('?')[0]; const lastCode = decryptUid[decryptUid.length - 1]; rdmcode = await redis.get(redisType[lastCode]).get(token); } if (!rdmcode) { return false; } return rdmcode; }; class VerifyController extends Controller { // 确定登录页面 async toLogin() { const ctx = this.ctx; try { // 请求发出的源网址,适用于不同端用户登录不同域名网站 const origin_url = ctx.request.header.origin; // 请求发出的具体网址,适用于不同端用户登录同一域名的网站 // const { origin_url } = ctx.request.body; const result = await ctx.service.verify.toLogin(origin_url); if (result == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); return; } if (result) { const data = { redirect: result.dataValues.login_url + '?client_id=' + result.dataValues.temporary_id }; this.setResponse(ctx, 200, '跳转到登录页', "deconstruction", data); } else { this.setResponse(ctx, 404, '未找到登录页', "none"); } } catch (error) { const blockName = fileName + "--" + "toLogin"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 确定登录状态 async loginStatus() { const ctx = this.ctx; try { const body = ctx.request.body; const uid = this.decryptRequest(body.data).split('?')[0]; const lastCode = uid[uid.length - 1]; const status = await ctx.app.redis.get(redisType[lastCode]).get(uid); const client = await ctx.service.verify.loginClient(body.client_id); if (client == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); return; } if (status !== null && client.dataValues.login_url == ctx.request.header.referer.split('?')[0] && client.dataValues.client_id == JSON.parse(status).clientId) { const timestamp = new Date().getTime(); const serverType = ctx.service[modelType[lastCode]]; await serverType.loginStatus(uid, 1); const data = { data: this.encryptRequest(uid + '?' + timestamp), access_token: JSON.parse(status).accessToken, refresh_token: JSON.parse(status).refreshToken, redirect: client.dataValues.client_url + '?' + body.data, }; this.setResponse(ctx, 200, '已登录', "deconstruction", data); } else { const serverType = ctx.service[modelType[lastCode]]; await serverType.loginStatus(uid, 0); this.setResponse(ctx, 404, '未登录', "none"); } } catch (error) { const blockName = fileName + "--" + "loginStatus"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 退出登录 async unLogin() { const ctx = this.ctx; try { let rdmcode = await checkUid(this); if (!rdmcode) { this.setResponse(ctx, 401, 'token过期或错误', "none"); return; } const uid = JSON.parse(rdmcode).uid; const lastCode = uid[uid.length - 1]; const serverType = ctx.service[modelType[lastCode]]; if(modelType == 'B' || modelType == 'C' || modelType == 'M') await serverType.loginStatus(uid, 0); const redisDbType = redisType[lastCode]; await ctx.app.redis.get(redisDbType).del(ctx.request.body.access_token); await ctx.app.redis.get(redisDbType).del(ctx.request.body.refresh_token); await ctx.app.redis.get(redisDbType).del(uid); this.setResponse(ctx, 200, 'unLogin', "none"); } catch (error) { const blockName = fileName + "--" + "unLogin"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 获取 token async getToken() { const ctx = this.ctx; try { const body = ctx.request.body; let code = body.code, type = this.decryptRequest(body.type), codeObj, typeMark = type, accessToken, refreshToken; if (type === 'code') { codeObj = await ctx.app.redis.get('db3').get(code); if (!codeObj) { typeMark = 'passLogin'; code = this.decryptRequest(code).split('?')[0]; const redisDbType = redisType[code[code.length - 1]]; codeObj = await ctx.app.redis.get(redisDbType).get(code); if (!codeObj) return codeObj; accessToken = JSON.parse(codeObj).accessToken; refreshToken = JSON.parse(codeObj).refreshToken; codeObj = await ctx.app.redis.get(redisDbType).get(refreshToken); } } else { type = type.split('?')[0]; const redisDbType = redisType[type[type.length - 1]]; codeObj = await ctx.app.redis.get(redisDbType).get(code); } if (!codeObj) { this.setResponse(ctx, 402, '请重新登录', "none"); } else { const client_id = JSON.parse(codeObj).clientId; const client = await ctx.service.verify.getToken(client_id); const timestamp = new Date().getTime(); const origin_url = ctx.request.header.origin; if (client == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); } else if (client && typeMark == "passLogin") { const data = { data: this.encryptRequest(JSON.parse(codeObj).uid + '?' + timestamp), access_token: accessToken, refresh_token: refreshToken, redirect: origin_url }; this.setResponse(ctx, 200, '验证通过', "deconstruction", data); } else if (client && typeMark !== "passLogin") { const redisCode = { code, type }; const result = await ctx.curl('http://127.0.0.1:' + ctx.app.server.address().port + '/user/token', { dataType: 'json', contentType: 'application/x-www-form-urlencoded', method: 'POST', timeout: 3000, data: { grant_type: 'authorization_code', code: JSON.stringify(redisCode), client_id: client.dataValues.client_id, client_secret: client.dataValues.client_secret, redirect_uri: 'http://127.0.0.1:' + ctx.app.server.address().port + '/getToken/', }, }); if (result.status == 200) { const data = { data: this.encryptRequest(result.data.access_token.uid + '?' + timestamp), access_token: result.data.access_token.token, refresh_token: result.data.refresh_token, redirect: client.dataValues.client_id == "insiders-manager" ? origin_url : client.dataValues.client_url } this.setResponse(ctx, 200, '验证通过', "deconstruction", data); } else { this.setResponse(ctx, 402, '请重新登录', "none"); } } else { this.setResponse(ctx, 402, '请重新登录', "none"); } } } catch (error) { const blockName = fileName + "--" + "getToken"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 验证token async getMsg() { const { ctx } = this; try { // 客户端实现 // 访问 /user/token 端口验证 accessToken,获取用户信息 let accessToken = { access_token: ctx.request.header.authorization, uid: this.decryptRequest(ctx.request.body.data).split('?')[0] }; const result = await ctx.curl('http://127.0.0.1:' + ctx.app.server.address().port + '/user/authenticate', { dataType: 'json', contentType: 'application/x-www-form-urlencoded', method: 'POST', timeout: 3000, data: { status: 'success', access_token: JSON.stringify(accessToken) }, }); if (result.status == 200) { let uid = result.data.data.token.user.uid; let lastCode = uid[uid.length - 1]; const userdata = await ctx.service[modelType[lastCode]].uidfinder(uid); if (userdata == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); return; } const timestamp = new Date().getTime(); const encryptData = this.encryptRequest(userdata.uid + '?' + timestamp); if (userdata) { const data = { data: encryptData }; this.setResponse(ctx, 200, '验证通过', "deconstruction", data); } else { this.setResponse(ctx, 401, 'token错误或过期', "none"); } } else { this.setResponse(ctx, 401, 'token错误或过期', "none"); } } catch (error) { const blockName = fileName + "--" + "getMsg"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } async show() { const ctx = this.ctx; try { const data = { data: ctx.state.oauth }; this.setResponse(ctx, 200, '返回信息', "deconstruction", data); } catch (error) { const blockName = fileName + "--" + "show"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 获取用户基本信息 async getUser() { const ctx = this.ctx; try { let rdmcode = await checkUid(this); if (!rdmcode) { this.setResponse(ctx, 401, 'token过期或错误', "none"); return; } const uid = JSON.parse(rdmcode).uid; const lastCode = uid[uid.length - 1]; const userData = await ctx.service[modelType[lastCode]].getUser(uid); if (userData == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); return; } if (userData) { const data = { userData }; this.setResponse(ctx, 200, '获取用户基本信息成功', "deconstruction", data); } else { this.setResponse(ctx, 404, '获取用户基本信息失败', "none"); } } catch (error) { const blockName = fileName + "--" + "getUser"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 修改用户基本信息 async editUser() { const ctx = this.ctx; try { let rdmcode = await checkUid(this); if (!rdmcode) { this.setResponse(ctx, 401, 'token过期或错误', "none"); return; } const uid = JSON.parse(rdmcode).uid; const body = ctx.request.body; const lastCode = uid[uid.length - 1]; const userData = await ctx.service[modelType[lastCode]].editUser(body.userMsg, uid); if (userData == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); return; } if (userData[0] != 0) { this.setResponse(ctx, 200, '修改用户基本信息成功', "none"); } else { this.setResponse(ctx, 404, '修改用户基本信息失败', "none"); } } catch (error) { const blockName = fileName + "--" + "editUser"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 修改密码 async changePassword() { const ctx = this.ctx; try { let rdmcode = await checkUid(this); if (!rdmcode) { this.setResponse(ctx, 401, 'token过期或错误', "none"); return; } const uid = JSON.parse(rdmcode).uid; const lastCode = uid[uid.length - 1]; const body = ctx.request.body; const oldPassword = this.decryptRequest(body.passwordForm.oldPassword); const newPassword = this.decryptRequest(body.passwordForm.newPassword); const changeList = await ctx.service[modelType[lastCode]].changePassword(uid, oldPassword, newPassword); if (changeList == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); return; } if (changeList && changeList[0] !== 0) { this.setResponse(ctx, 200, '修改密码成功', "none"); } else { this.setResponse(ctx, 404, '修改密码失败', "none"); } } catch (error) { const blockName = fileName + "--" + "changePassword"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } // 重置密码 async resetPassword() { const ctx = this.ctx; try { let rdmcode = await checkUid(this); if (!rdmcode) { this.setResponse(ctx, 401, 'token过期或错误', "none"); return; } const uid = JSON.parse(rdmcode).uid; const lastCode = uid[uid.length - 1]; const body = ctx.request.body; const model = this.decryptRequest(body.model); const defaultPassword = this.decryptRequest(body.defaultPassword); const password = this.decryptRequest(body.password); const requestMsg = body.userMsg; const resetType = body.resetType; const resetList = await ctx.service[modelType[lastCode]].resetPassword(uid, model, defaultPassword, password, requestMsg, resetType); if (resetList == "error") { this.setResponse(ctx, 500, '服务器错误', "none"); return; } if (resetList) { this.setResponse(ctx, 200, '重置密码成功', "none"); } else { this.setResponse(ctx, 404, '重置密码失败', "none"); } } catch (error) { const blockName = fileName + "--" + "resetPassword"; ctx.app.middleware.log('../../controllerLog', blockName + ">>>>" + error); this.setResponse(ctx, 500, '服务器错误', "none"); } } } module.exports = VerifyController;