基于JWT的单点登录方案

cookie机制

  • 关于cookie和seesion的联系
  • cookie中会包含那些信息
  • 名字,值,过期时间,路径,域
  • cookie会带到http请求头中发送给服务端
  • 如果cookie没有设置过期时间的话,那么cookie的默认生命周期是浏览器的会话。

session机制

  • 1,session是容器对象,客户端在请求服务端的时候,服务端会根据客户端的请求判断是否包含了jsessionId的标识
  • 2,如果已经包含了,说明客户端之前已经创建了会话。sessionId是一个唯一的值
  • 3,如果sessionid不存在,那么服务端为这个客户端生成一个sessionid. JESSIONID。

       session       cookie 存储的是JSESSIONID  

       session存储在服务器端  cookie存储在浏览器端

       服务器端(Tomcat) 会生成一个唯一的sessionId号存储在cookie中 叫 jessionid

       在服务器端(tomcat)中存储serssion 使用concurrentMap (ConcurrentMap   key JSESSIONID  values session)

       浏览器端下次请求服务器端是将jsessionId带过来 找到对应的session 获取session中存储的信息(用户信息)

解决方案:

  • Session Sticky : 是指让同一客户端的请求,落在同一台服务器上,因为不会落在别的服务器上,所以自然就不会出现跨域问题。但是这个方案的缺点非常的明显,就是不管比采用什么算法,用户的请求落在哪一台服务器上都是由用户来决定的,可能会造成单点压力,并且如果一台服务器出问题,可能会造成一片区域的人无法访问。
  • Session复制 :是指服务器之间互相同步session信息,也就是说每台服务器上都保存着所有的session信息。这样做的缺点也是非常明显的。上文提到过,session是存在内存中的,会严重影响服务器性能,当然,你也可以把他存在数据库中,但是这会大大影响响应速度。还有一个缺点就是,当访问量过大时,由于互相同步的问题,会造成大量的网络开销。
  • Session集中存储:是指把Session集中存储在一个第三方的服务器中,可以是Redis,可以是数据库或是其它什么东西。当需要访问的时候,都去这个服务器去查。这样做也有不小的缺点,首先是单点问题,如果这个服务器宕机,那么所有的服务都是不可用的,所以这里必须做集群,会浪费服务器资源。还有一点是,每次验证都需要来这个服务器来查,会凭白增加一次网络开销,降低访问速度。
  • Cookie :状态信息不再保存在服务端,而是保存在客户端,客户端每次访问服务器的时候,把这个信息带给服务器。但是Cookie也有不少问题,最被人关注的就是安全问题,因为信息是保存在客户端的,就比较容易被人盗取、篡改,当然这些安全问题都是有解决方案的,这不是限制Cookie的主要原因,真正限制Cookie的原因是很多设备不支持Cookie。
  • Token : 和Cookie类似,Token也是由客户端来维持状态的,信息存储在客户端内,具有平台无关性。Token实质上是服务端给客户端的一个字符串,上面包含着一些验证信息,相当于一个身份令牌,你拿着这个令牌就能得到他的服务。相比较于Cookie,Token更加的灵活,可以在任何地方生成,基于Token的权限系统是非常容易实现的。

基于JWT的解决方案

json web Token客户端和服务端信息安全传递,身份认证的一种解决方案,用在登陆上jwt由三个组成:header,payload 载荷,signature

JWT包含三部分数据:

  • Header:头部,通常头部有两部分信息:

    • 声明类型,这里是JWT

    • 加密算法,自定义

    我们会对头部进行base64加密(可解密),得到第一部分数据

  • Payload:载荷,就是有效数据,一般包含下面信息:

    • 用户身份信息(注意,这里因为采用base64加密,可解密,因此不要存放敏感信息)

    • 注册声明:如token的签发时间,过期时间,签发人等

    这部分也会采用base64加密,得到第二部分数据

  • Signature:签名,是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥(secret)(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和可靠性

基于JWT的单点登录方案_第1张图片

    Base64(header).Base64(payload)  +  head中定义的算法 +密钥  生成一个字符串    str.签名字符串  就是 JWT的token

步骤翻译:

  • 1、用户登录
  • 2、服务的认证,通过后根据secret(密钥)生成token
  • 3、将生成的token返回给浏览器
  • 4、用户每次请求携带token
  • 5、服务端利用密钥解读jwt签名,判断签名有效后,从Payload中获取用户信息
  • 6、处理请求,返回响应结果

        因为JWT签发的token中已经包含了用户的身份信息,并且每次请求都会携带,这样服务的就无需保存用户信息。

微服务中的一种解决方案:

注意:公钥和私钥的区别

  • 公钥加密,持有私钥才可解密
  • 私钥加密,持有私钥或公钥才可以解密

没有RSA(非对称)加密时

在微服务架构中,我们可以把服务的鉴权操作放到网关中,将未通过鉴权的请求直接拦截,如图:

基于JWT的单点登录方案_第2张图片

  • 1、用户请求登录
  • 2、Zuul将请求转发到授权中心,请求授权
  • 3、授权中心校验完成,颁发JWT凭证
  • 4、客户端请求其它功能,携带JWT
  • 5、Zuul将jwt交给授权中心校验,通过后放行
  • 6、用户请求到达微服务
  • 7、微服务将jwt交给鉴权中心,鉴权同时解析用户信息
  • 8、鉴权中心返回用户数据给微服务
  • 9、微服务处理请求,返回响应

发现什么问题了?

每次鉴权都需要访问鉴权中心,系统间的网络请求频率过高,效率略差,鉴权中心的压力较大。

结合RSA的鉴权

公钥可以有多份,私钥一份就可以。

基于JWT的单点登录方案_第3张图片

  • 我们首先利用RSA生成公钥和私钥。私钥保存在授权中心,公钥保存在Zuul和各个微服务
  • 用户请求登录
  • 授权中心校验,通过后用私钥对JWT进行签名加密
  • 返回jwt给用户
  • 用户携带JWT访问
  • Zuul直接通过公钥解密JWT,进行验证,验证通过则放行
  • 请求到达微服务,微服务直接用公钥解析JWT,获取用户信息,无需访问授权中心

你可能感兴趣的:(【微服务】)