将登录状态放到session真的好吗?
来源:10-1 登录功能实现
Yoooshiki
2018-08-10
老师您好,我是做Java的,一般来说,我们不会将登录状态放到session中,因为如果是分布式系统,有多台服务器的话,每一次的请求不一定落到哪台服务器,因此我们的常用套路是做分布式session,也就是将登录状态保存到redis中,然后多数需要做权限认证的接口都会做拦截,查询redis中是否有用户的登录状态。
这里的话是直接将状态保存到session中吗?应该也可能存在分布式的情况吧?
写回答
1回答
-
Yoooshiki
提问者
2018-08-10
首先说一下,我上面说的放到session里不好,指的是放到服务器内存。而且我down下来了老师的代码,没发现将状态保存到session的,所以晚上用了点时间,自认为算是完美解决吧:
$ npm install uuid $ npm install redis
一、登录、登出功能
//Redis let redis = require('redis') let client = redis.createClient() //uuid const uuidv4 = require('uuid/v4') //v4是随机数 //登录 router.post('/login', function (req, res, next) { let param = { userName: req.body.userName, userPwd: req.body.userPwd } User.findOne(param, (err, doc) => { if (err) { res.json({ status: "1", msg: err.message }) } else { let uuid = uuidv4() //存至cookie res.cookie("token", uuid, { path: "/", maxAge: 1000 * 60 * 60 //存储1小时 }) //存至redis, 1小时失效 client.set(`token-${uuid}`, JSON.stringify(doc)) client.expire(`token-${uuid}`, 60 * 60); res.json({ status: "0", msg: "", result: doc.userName }) } }) }); //登出 router.post('/logout', function (req, res, next) { let cookie = req.cookies.token if (cookie) { //清除redis client.del(`token-${cookie}`) //清除cookie res.cookie("token", "", { path: "/", maxAge: 0 }) } res.json({ status: "0", msg: "", result: "" }) });二、登录拦截功能
//Redis let redis = require('redis') let client = redis.createClient() client.on('ready', function (err) { console.log('Redis ready'); }); //拦截放在路由之前,只要有请求进来就先判断的 app.use(function (req, res, next) { //接口白名单 if ( req.originalUrl == '/users/login' || req.originalUrl == '/users/logout' || req.path == "/goods/list" //因为后面有参数,只取接口的pathName. 或者 req.originalUrl.indexOf('/goods/list') > -1 ){ next() return } //验证登录状态 let cookie = req.cookies.token //查询cookie if (!cookie) { res.statusCode = 401 res.json({ status: '401', msg: '当前未登录', result: '' }); } //查询redis client.get(`token-${cookie}`, (err, reply) => { if (!reply) { res.statusCode = 401 res.json({ status: '401', msg: '当前未登录', result: '' }); }else next() }) }); app.use('/', indexRouter); app.use('/users', usersRouter); app.use('/goods', goodsRouter);这样的话,如果没有登录,响应码设置为401,前端就可以通过axios拦截器拦截到401,跳转到登录页或者提醒登录。
032020-08-16
相似问题