用户登录的状态如何保存?如何方便的保存?如何安全的保存?
背景
项目中的登录功能必不可少,登录之后状态是怎么保存的呢,客户端是如何知道我们登录了没有呢?
由于本人是前端开发,所以对这块不太了解,学习时记录一下,加深理解...
客户端保存登录状态
客户端保存登录状态一般是用cookie
,cookie
是客户端和服务端都能操作的,在用户登录成功之后,可以在服务端写入cookie,在nodejs中如下:
javascript
//nodejs
// 获取 cookie 的过期时间
const getCookieExpires = () => {
const d = new Date()
d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
console.log('d.toGMTString() is ', d.toGMTString())
return d.toGMTString()
}
// 限制前台修改cookies httpOnly
// 限制过期时间 expires=${getCookieExpires()
res.setHeader("Set-Cookie",`userId=${req.userId};path=/;httpOnly; expires=${getCookieExpires()}`)
因为浏览器是可以直接修改cookie
的,所以要加上httpOnly
限制。
客户端用cookie
保存的缺点:
- cookie暴露很危险,任何人都能看到
- 没加httpOnly限制的话可以随意更改
所以,为了解决这个问题,我们用服务端来存储关键信息
服务端保存登录状态
那么服务端存储我们自然想到可以使用session来存储。怎么把客户端和用户信息对应起来呢?
我们不是就完全放弃cookie
了,我们还是要用cookie
和seesion
配合起来:
既然cookie
不能存储关键隐私信息,那么我们就存一个无关紧要的唯一标识
就行了,然后拿这个标识与用户信息的session
建立映射关系,当用户请求携带了这个cookie
,我们去session
中找到对应的用户信息就可以了
在nodejs中:
然后再登录成功的逻辑中,把用户信息存进去就行了。
这样我们就可以安全的保存我们的用户信息了。
但是...
凡事都有但是...
这样做还不行,安全是安全了,但是用起来不方便,怎么不方便呢?
session的问题 session是js 变量,放在nodejs进程内存中。
-
第一,进程内存有限,访问量过大,内存暴增怎么办?
-
第二,正式上线是多进程,进程之间无法共享。现在企业都是在一台机器上跑多个node进程来提升效率和使用率,但是每个进程的内存是相互隔离的,所以登录状态没法共享
-
第三 , session会在服务端关闭时释放存储空间,但服务端每次更新都要重启,或者运维同学运维也要重启,导致频繁的需要用户登录体验不好
怎么解决这个问题?方案:redis
- 第一:
redis集群可以突破内存限制
- 第二:
只要redis不重启数据就不会消失
- 第三:
存在redis的数据每个node进程都可以访问
- 第四:
redis性能好速度快
我们在登录完成之后,把用户的信息放在redis里面,获取的时候也从里面获取。
这样就可以放心的使用用户信息了。