//基础的路由定义 const router = require('express')(); var session = require('express-session'); const { loginUser, userCenter } = require('../model/UserModel'); const response = require('../helper/Response'); const permssion = require('../helper/Permission'); const loginedContainer = require('../helper/LoginedContainer'); const tools = require('../core/tools'); const TokenManager = require('../helper/TokenManager'); const userManager = userCenter(); //用户退出事件 router.post('/loginout', function (req, res) { if (!req.xhr) return; MCSERVER.log('[loginout] 用户:' + req.session['username'] + '退出'); //删除一些辅助管理器的值 if (req.session['username'] && req.session['login']) loginedContainer.delLogined(req.sessionID); TokenManager.delToken(req.session['token']); //退出后的 Session 并不会立刻反馈到所有 Session 上 req.session['login'] = false; req.session['username'] = undefined; req.session['token'] = undefined; req.session.destroy(); response.returnMsg(res, 'user/logout', 'loginOut'); }); MCSERVER.login._banip = 0; function LoginRule(ip) { let count = MCSERVER.login[ip] || 0; if (count > 10) { //值触发一次定时器 if (count == 11) { setTimeout(() => { MCSERVER.login[ip] = 0; }, 1000 * 60 * 10); } return false; } return true; } //唯一性登录检查 function OnlyLoginCheck(sessionID) { for (let k in MCSERVER.allSockets) { if (MCSERVER.allSockets[k].sessionID == sessionID) { return true; } } return false; } const counter = require('../core/counter'); //用户登录请求路由 router.post('/login', function (req, res) { if (!req.xhr) return; let ip = req.socket.remoteAddress; let username = req.body.username || ''; let password = req.body.password || ''; let enkey = req.session['login_md5key'] || ''; //登陆规则 if (!LoginRule(ip)) { response.returnMsg(res, 'login/check', "密码错误次数过多!您已被锁定!请10分钟之后再进行登录!"); return; }; //判断是否有 ws 正在连接 if (OnlyLoginCheck(req.sessionID)) { response.returnMsg(res, 'login/check', "您已在此浏览器登录过账号,请关闭所有与服务器的链接网页并退出账号!"); return; } //同 Session 只可登录一个 用户 if (loginedContainer.isLogined(req.sessionID)) { response.returnMsg(res, 'login/check', 302); return; } //登陆次数加一 counter.plus('login'); MCSERVER.log('[Login]'.green, '用户尝试登陆:', username, "密匙:", password); loginUser(username, password, (loginUser) => { //只有这里 唯一的地方设置 login = true req.session['login'] = true; req.session['username'] = loginUser.dataModel.username; req.session['dataModel'] = loginUser.dataModel; //Only read req.session['login_md5key'] = undefined; req.session.save(); delete MCSERVER.login[ip]; //添加到 login 容器 注意,全部代码只能有这一个地方使用这个函数 loginedContainer.addLogined(req.sessionID, username, loginUser.dataModel); MCSERVER.log('[Login]'.green, '用户:', username, "密匙正确", "准许登录"); response.returnMsg(res, 'login/check', true); }, () => { //密码错误记录 MCSERVER.login[ip] ? MCSERVER.login[ip]++ : MCSERVER.login[ip] = 1; //防止数目过于太大 溢出 MCSERVER.login[ip] > 1000 ? MCSERVER.login[ip] = 1000 : MCSERVER.login[ip] = MCSERVER.login[ip]; //passwordError counter.plus('passwordError'); req.session['login'] = false; req.session['username'] = undefined; req.session['login_md5key'] = undefined; req.session['dataModel'] = undefined; req.session.save(); //删除到 login 容器 if (req.session['username']) loginedContainer.delLogined(req.sessionID); MCSERVER.log('[Login]'.green, '用户:', username, "密匙错误", "拒绝登录"); response.returnMsg(res, 'login/check', false); }, enkey); }); //用户请求登录键路由 router.get('/login_key', function (req, res) { if (!req.xhr) return; let username = req.query.username || null; let md5Key = req.session['login_md5key'] || tools.randomString(32); let okflag = true; //拒绝掉已登录用户 if (!username || loginedContainer.isLogined(req.sessionID)) okflag = false; req.session['login_md5key'] = md5Key; //取salt let loggingUser = userManager.get(username); //是否存在用户名 && Flag is true if (loggingUser && okflag) { res.send(JSON.stringify({ //salt enkey1: loggingUser.dataModel.salt, //md5Key enkey2: md5Key })); return; } //这里是 随机的 salt 与 md5key 因为用户根本不存在,则返回一个随机的类似于正常的信息,让前端判断错误 //防止轻而易举的遍历用户名,但这仍然可以通过两次或三次尝试判断用户名是否存在 res.send(JSON.stringify({ enkey1: tools.randomString(6), enkey2: tools.randomString(32) })); }); //模块导出 module.exports = router;