【实习日志】JWT + Redis 实现单点登录
文章目录JWT + Redis 实现单点登录1、以前如何登录?2、JWT是什么?3、认证流程4、Token + RedisJWT + Redis 实现单点登录模拟场景:实习好长时间,代码还没敲上,那得有所收获啊,虽然啥也没干,那我就胡诌一个吧,项目中要实现一个单点登录功能,虽然不是我敲的,那我说明白了,那这是不是就是我做的呢?1、以前如何登录?我们知道http协议是无状态的,有这样一个场景,我们购
JWT + Redis 实现单点登录
模拟场景:实习好长时间,代码还没敲上,那得有所收获啊,虽然啥也没干,那我就胡诌一个吧,项目中要实现一个单点登录功能,虽然不是我敲的,那我说明白了,那这是不是就是我做的呢?
1、以前如何登录?
我们知道http协议是无状态的,有这样一个场景,我们购物的时候需要访问多个页面,加入购物车一个页面,那么在不同页面进行切换时,因为是无状态,那么就需要登录,这对用户体验是十分不友好的,那么如何实现登录一次,可以跳转多个页面呢?这就有了cookie和session的存在。
按照以往的登录方式
- 用户向服务器发送账号密码
- 服务器从数据库中查询进行验证,假如登录成功,则开启一个会话(session),将用户信息存入会话中,如用户角色、登录时间等信息
- 服务器产生一个session_id返回给用户,存入cookie中
- 下次用户访问页面时带着这个cookie访问服务器,服务器从cookie中获取session_id,来判断用户身份
但是这种传统的登录方式有两点不太友好:
- 服务端保存了大量数据,增加了服务器的压力
- 客户端比较依赖服务端,每次请求必须请求同一台服务器,限制了应用的扩展性
- CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。
针对第二点,我认为是最主要的缺点,因为用户的信息是保存在服务器中的,下次登录必须访问同一台服务器,这对单机还好,但是现在基本上都是分布式微服务,那么就涉及到多个服务器,那么假如还要按照以前的方式,就要考虑session共享。那么有没有更好的方式呢?
JWT横空出世。
2、JWT是什么?
JWT:Json Web Token,就是一个Json格式的字符串,由三部分组成:Header、Playload、Signature。三部分之间用 ‘.’ 分隔。
相较于session,它是无状态的,session是保存在服务端的,而 JWT 则是保存在客户端,所以一定程度上减轻了服务器的压力。
- Header:头部,有两部分组成,一个是类型type,这里类型就是 JWT,另一个是加密算法algorithm。这里写的是HS256,表示下面使用的加密方式。
{
'typ': 'JWT',
'alg': 'HS256'
}
- Playload:载荷,主要是一些用户信息,比如用户名,用户权限,签发日期,过期时间等。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Header和Playload最后转换为Base64进行加密,注意这里的加密是可以被破解还原的,不够安全,所以一些重要敏感的信息不要放在这里。
- Signature:签证,主要验证信息就是在这里,由三部分组成,base64后的header和Playload+私钥,然后将其三部分使用header里面的加密算法进行加密,最后构成这个signature。
所以这里最重要的部分就是私钥,它是由我们自定义,保存在服务器端,所以不要让别人知道私钥是什么。
3、认证流程
知道这些基础概念之后,那么在实际生产这些是怎么应用的呢?
- 用户登录,输入账号密码发送请求给服务器,第一次登录,服务器会从数据库中查询数据,判断是否登录成功。
- 假如数据库查询成功,根据用户信息+服务器保存的私钥生成token信息,返回给客户端,服务端不保存token信息。
- 下次访问,用户就会携带token信息,服务器通过对token进行解码然后进行验证,验证这个token是不是自己的生成的,判断token是否过期,以此来判断是否允许访问,然后对客户端进行响应。
那么这有一个什么问题呢?就是 jwt 一旦生成就无法篡改,我们在生成jwt的时候指定了过期时间,一旦下发服务器就无法拒绝 jwt 的请求,另外时间是固定的。为了解决时间固定这个问题,我们可以采用token + redis的方式。
4、Token + Redis
没有特别十全十美的技术,我们需要做的是根据不同的应用场景去选择相应的技术,我们为了让过期时间灵活一下,则是采用了 token + redis。
大致的流程的是根据用户信息生成一个key,不同的用户以及不同的登录方式会有不同的过期时间,比如PC端和手机端有不同的过期时间,用户和管理员有不同的过期时间,然后以此信息生成 token,将 token 作为value,存储到redis中,假如是再次登录,则会延迟过期时间。
那么这又有一个问题,JWT 是天然的去中心化,那么使用了 Redis 之后又变得中心化,各有优劣,根据项目在去取舍。
用到了 Redis ,又要涉及到 Redis 挂了的问题,又要涉及到集群,读写分离、主从复制。根据 Redis 往下扩展,咱们下篇再叙。
骚年啊骚年,路还很长。
更多推荐



所有评论(0)