redis是一个内存数据库,和类似mysql这种硬盘关系型数据库相比,它的典型特点就是数据存储在内存中,访问速度快。通常,我们在处理用户登陆权限的问题中,就是使用redis来存储用户的session信息,它适合的典型场景就是:访问比较频繁的数据。
背景知识
http是一个无状态协议,由于http的无状态性,为了使某个域名下的所有网页能够共享某些数据,session和cookie出现了.
什么是session?
session是一种服务器端的
状态管理技术。
当浏览器访问服务器时,服务器创建一个session对象(该对象有一个唯一的id号,称之为sessionId),服务器在默认情况下,会将sessionId以cookie的方式(set-cookie消息头)发送给浏览器,浏览器会将sessionId保存到内存。当浏览器再次访问服务器时,会将sessionId发送给服务器,服务器依据sessionId就可找到之前创建的session对象。
- 客户端访问服务器端的流程:

cookie-session认证机制
用户向服务器发送用户名和密码,认证成功之后,服务端会在当前会话session中保存相应信息(比如用户角色等)
服务器向用户返回一个 session_id,写入用户的 Cookie
用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器
服务器收到 session_id,找到前期保存的数据,由此得知用户的身份
用cookie存储用户敏感信息session行不行?
如果全部用cookie,数据量大的时候客户端是没有那么多空间的。账户信息全部保存在客户端,
一旦被劫持,全部信息都会泄露。
并且客户端数据量变大,网络传输的数据量也会变大(
每次http请求的头中都携带cookie信息)
cookie-session存在的问题
扩展性不好,不适合服务器集群共享session,所以一般都是引入 session 数据持久化 - 写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败
使用redis存储session
- 根据上面的介绍,大家应该明白了cookie-session来验证用户信息的机制,但是有人会问,既然你启动nodejs服务,他会启动一个进程,为什么要使用redis来存储session的信息,而不用nodejs进程的内存来存储?
不同的操作系统会限制进程的内存大小(32位操作系统最大分给nodejs进程0.7G/64位操作系统为1.4G)
单个进程的内存有限,硬件的内存远大于此,资源浪费。
进程之间的数据是隔离的,而且一般线上环境都是多进程的。会造成系统异常。
koa2中使用redis(redis-server和redis-cli)
启动redis-server
redis-server
启动redis-cli
redis-cli // 显示127.0.0.1:6379
nodejs中连接redis
1)安装启动redis
npm i redis –save
2)读取配置建立redisClient
1 | /** |
在koa中使用redis存储session
npm i koa-redis koa-generic-session --save安装插件
app.js引入中间件
1 | // 引入redis的配置 |
在路由中使用ctx.session
1 | router.get('/test', async (ctx, next) => { |
可以看到/test的请求cookie中已经存在
sessionId:xxxxx,而且在redis-cli中输入keys *也可以看到一个blog:sess:为前缀的key -blog:sess:xxxxxx,key的后半部分xxxxx和cookie中的xxxxx值一样。
在redis-cli中输入ttl可以查看redis的过期时间和cookie的过期时间也是差不多的(redis的过期时间为s,cookie为ms)
在登陆权限控制中的使用
在login登陆之后,可以将用户的信息,比如username存入redis中(ctx.username=username),然后同一个用户在请求后台的时候,就会从cookie中获取sessionId,查询redis中存储的username信息
就可以在中间件中,根据ctx.username是否存在判断用户是否登陆。有访问权限。
redis常用操作(持续补充)
get key 获取数据
set key value 设置数据
keys * 所有的key列表
flushall 可以清除所有数据库的值
flushdb 清除当前数据库的值
exit 退出