登录的设计方案

前言

  最近趁着离职在家的时间做了个视频播放项目,本来想着部署到服务器上,结果 额,,,阿里服务器只有2g2核,无奈= =,只好部署到虚拟机上了,在整个项目做完之后,在总结的时候有一些心得就写在博客上了,有问题大家留言~

  在做过的项目里,我总结了下,在说关于登录的设计之前我们需要了解下session和cookie

session

  因为http协议是无状态的,我们无法知道客户端在访问服务器时候的状态是什么样的,因此出现了session和cookie,session是存放在服务器上的,通过session我们可以知道客户端的会话状态,session对应java中的HttpSession,在getSession时会创建一个session,同时产生与之关联的sessionId,session会随着http响应,下次发出请求时候会在http头里带上sessionId,服务器根据sessionId来得到与之对应的id得到与之对应的session。由于session存放于服务器端,也会出现问题:1.在集群模式下,需要对session做一个转移同步 2.session会消耗服务器端的存储。

cookie

  HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。Cookie实际上是一小段的文本信息(key-value格式)。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。

在了解完session和cookie后我们再来看一下jwt的概念

登录设计

  在设计方案中,有两种,一种是和session有关,另一种是和cookie有关,下来我们依次介绍:

session设计

  我们用session作为登录标志的话,会存在内存消耗和集群一致性问题,为了解决这个问题,我们可以把sessionId存放在redis中作为token,流程图如下:

image.png

  浏览器的请求过来访问服务器,先会走网关,在网关里我们做了过滤器来过滤请求,看请求中是否携带了token,如果携带了token再去redis中查询是否存在,存在的话则chain.filter放行,如果token不存在或者redis中不存在表示会话过时,需要重新登录,这时候前端会跳转到登录界面,这次的请求就会访问user服务,验证用户名和密码正确之后,通过HttpSession.getSession(),获取到session,再将业务名+sessionId作为key,用户信息作为value存放到redis中,sessionId作为token返回给前端,前端下次访问的时候会带上sessionId,这样我们就确定了用户是否登录,这样的设计思路既的好处是:session做了同步转移,又减少了服务器的压力,也减少了user服务的访问量,不必每次都来查看用户名密码是否正确,缺点是虽然将session存到了redis中但是无疑增加了系统的复杂性,session依赖于cookie,但是移动端经常没有cookie,并且如果浏览器仅用了cookie,还需要在url后面添加sessionId。

  在了解基于cookie的登录认证之前,我们需要先了解一下JWT

JWT

  token的一种具体实现方式,其全称是JSON Web Token,官网地址:jwt.io/ ,整个格式是json格式,JWT由三部分组成:

标头( 头部包括令牌的类型(eg:JWT) 使用的哈希算法(eg:RSA))

负载(存放有效信息第地方,比如签发者、过期时间、也可以自定义(eg: 用户的基本信息))

签名( 签名,此部分防止jwt被篡改,这个部分用base64url将前两部分进行编码 )

非对称加密算法

 加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。私钥加密的信息,只有公钥才能解密。
常见的非对称加密算法:RSA,ECC

cookie设计

  这是我做之前项目的时候使用的登录授权,cookie的安全性一直是一个问题,虽然将HttpOnly设置为true可以防止js脚本窃取信息,但是为了安全起见我们还是需要对token进行加密,保证用户信息的安全,设计图如下:

image.png

  除授权服务外,每个服务配置文件里都存放这公钥,授权服务中存放着对应的私钥,请求来的时候走网关,网关中的filter会对token使用公钥进行解密,解密成功,则对cookie里的token刷新过期时间,返回200,跳转界面,解密失败则返回,到登录界面登录之后走到授权服务,来到授权服务里,先验证完用户名和密码,之后使用JWT工具,使用私钥对用户信息加密,生成JwtToken,最后再将token写入cookie,设置过期时间,并设置httpOnly设置为true,防止js脚本。

image.png

猜你喜欢

转载自juejin.im/post/7060376989059776549