登录业务的演变

单一服务器的模式登录业务

要想区分来自不同用户请求的话,服务端需要根据客户端的请求确认其用户的身份,即身份验证

在人机交互中,身份验证意味着要求用户登录才能访问某些信息。而为了确认身份,用户必须提供只有用户和服务器知道的信息(即身份验证因子),比如用户名/密码。

web环境下,由于HTTP是无状态的,那么服务器应该如何记住登录状态呢?

常见的身份验证方案分为2类:

  • 基于Cookie/Session的验证。
  • 基于Token的验证。

基于Cookie/Session的验证

由于 HTTP 是一种无状态的协议,客户端每次发送请求时,首先要和服务器端建立一个连接,在请求完成后又会断开这个连接。这种方式可以节省传输时占用的连接资源,但同时也存在一个问题:每次请求都是独立的,服务器端无法判断本次请求和上一次请求是否来自同一个用户,进而也就无法判断用户的登录状态

Cookie的工作原理

为了解决HTTP无状态的问题,Lou Montnull在1994年的时候,推出了Cookie

Cookie 指的就是在Cookie是服务端发送给客户端的一段特殊信息,这些信息以文本的方式存放在客户端,客户端每次向服务器端发送请求时都会带上这些特殊信息,Cookie仅仅是浏览器实现的一种数据存储功能。

注意:Cookie 功能需要浏览器的支持。如果浏览器不支持 Cookie(如大部分手机中的浏览器)或者把 Cookie 禁用了,Cookie 功能就会失效。不同的浏览器采用不同的方式保存 Cookie。IE 浏览器会以文本文件形式保存,一个文本文件保存一个 Cookie

有了Cookie之后,服务端就能够获取到客户端传递过来的信息了,如果需要对信息进行验证,还需要通过Session

客户端请求服务器,服务器端会为这次请求开辟一块内存空间,这个便是Session对象。

Seesion的工作原理

Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。

如果说 Cookie 机制是通过检查客户身上的 “通行证” 来确定客户身份的话,那么 Session 机制就是通过检查服务器上的 “客户明细表” 来确认客户身份。

session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的 “身份标识”,然后客户端每次向服务器发请求的时候,都带上这个 “身份标识”,服务器就知道这个请求来自于谁了。对于浏览器客户端,大家都默认采用 cookie 的方式,保存这个 “身份标识”。这也就是 Cookie + Session 登录。

服务器使用 session 把用户的信息临时保存在了服务器上,用户离开网站后 session 会被销毁。这种用户信息存储方式相对 cookie 来说更安全。

可是 session 有一个缺陷:如果 **web** 服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候 **session** 会丢失。

注意:Session 的使用比 Cookie 方便,但是过多的 Session 存储在服务器内存中,会对服务器造成压力。

Session与Cookie的联系
  • cookie数据存放在客户的浏览器上,session数据放在服务器上。
  • cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session
  • session会在一定时间内保存在服务器上。当访问增多,会比较占用你的服务器性能。考虑到减轻服务器性能方面,应当使用cookie
  • 单个cookie在客户端的限制是3k,就是说一个站点在客户端存存放的cookie不能超过3k。
Cookie与Session的实现流程

img

基于sesiion的方案中,登录成功后,服务端将用户的身份信息存储在Session里,并将session ID通过cookie传递给客户端。后续的数据请求都会带上cookie,服务端根据cookie中携带的session id来得到辨别用户身份。

代码演示:

//....
session.setAtrrbuite("user",user);

//...
session.getAttrbuite("user");
//...
Cookie+Seesion存在的问题

虽然我们使用Cookie+Session的方式完成了登录验证,担仍然存在一些问题:

  • 由于服务端需要对接大量的客户端,也就需要存放大量的Seesion ID,这样就会导致服务器压力过大。如果服务器是个集群,为了同步登录的状态,需要将Session ID同步到每一台服务器上,无形中增加了服务器端的维护成本。
  • 由于Session ID存放在Cookie中,所以无法避免CSRF攻击(跨站请求伪造)。

为了解决Session+Cookie 机制暴露出的诸多问题,我们可以使用Token的方式。

基于 token 的登陆认证

在大多数的使用Web API的互联网公司,Token是多用户处理认证的最佳方式。

一下几点特性会让你在程序中使用基于Token的身份验证

  • 无状态、可扩展。
  • 支持移动设备。
  • 跨程序调用。
  • 安全。

Session 方案中用户信息(以Session记录形式)存储在服务端。而Token方案中(以Token形式)存储在客户端,服务端仅验证Token合法性。这种区别在单点登录(SSOSingle Sign On)的场景最为明显:

  • 基于SessionSSO:考虑如何同步Session和共享Cookie。比如登录成功后把响应Cookiedomain设置为通配兄弟应用域名的形式,并且所有都从身份验证服务同步Session
  • 基于TokenSSO:考虑如何共享Token。比如进入兄弟应用时通过URL带上Token
基于Token的验证原理

基于Token的身份验证是无状态的,不将用户信息存在服务器中。这种概念解决了在服务端存储信息时的许多问题。NoSession意味着你的程序可以根据需要去增减机器,而不用去担心用户是否登录。

Token验证实现流程

而在基于Token的方案中,服务端根据用户身份信息生成Token,发放给客户端。客户端收好Token,并在之后的数据请求带上Token,服务端接到请求后校验并解析Token得出用户身份,过程如下:

img

把这个过程分为两步,步骤图及解析如下:

img

用户首次登录时:

  • 用户输入用户名和密码,并发送请求,访问a.com/pageA
  • 服务器端程序验证,账户密码无误,创建Token
  • 服务器端程序返回一个带签名的Token给客户端,客户端存储Token

后续页面访问时:

img

  • 客户端每次访问a.com/pageB都携带第一次登录时获取的Token到服务器端。
  • 服务端验证Token,校验成功则返回请求数据,校验失败则返回错误码。
Token的优势/特点
  • 无状态、可扩展

在客户端存储的Token是无状态的,并且能够被扩展。基于这种无状态的和不存储Session信息,所以不会对服务器端造成压力,负载均衡器能够将用户信息从一个服务器传到其他服务器上,即使是服务器集群,也不需要增加维护成本。

  • 安全性

请求中发送Token而不是发送Cookie,能够防止CSRF(跨站请求伪造)。即客户端使用Cookie存储了Tooken,Cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对Session的操作。Token也可以存放在前端任何地方,可以不用保存在Cookie中,提升了页面的安全性。

Token是有失效的,一段时间之后用户需要重新验证。

  • 可扩展性

Token能够创建与其他程序权限的程序。

  • 多平台跨域

用户名/密码属于知识因子,另外还有占有因子和遗传因子:

  • 知识因子:用户登录必须知道的东西都是知识因子,比如用户名、密码等。
  • 占有因子:用户登录时必须具备的东西,比如密码令牌、ID卡等。
  • 遗传因子:个人的生物特征,比如指纹、虹膜、人脸等。

身份验证中的Token就像身份证,由服务端签发/验证,并且在有效期内都具有合法性,**认证(Token)不认“人”(用户)**

Session方案中用户身份信息(以Session记录形式)存储在服务端。而Token方案中(以Token形式)存储在客户端,服务端仅验证Token合法性。

具体的Token的原理和使用:

https://blog.csdn.net/weixin_46487176/article/details/124139089?spm=1001.2014.3001.5501

https://www.theguagua.com/%E7%BC%96%E7%A8%8B/web/%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81/%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81%E7%9A%84%E4%B8%A4%E7%A7%8D%E6%96%B9%E5%BC%8F/

分布式集群部署下的登录业务

随着微服务的架构的到来,大多应用采用分布式集群部署,不同服务一般部署在不同的服务器中,如何才能达到在其中某一个服务登录之后,在其他服务不必再次登录的效果?这就诞生了单点登录SSOSingle Sign on)这个概念。

img

单点登录,简称SSO,是比较流行的企业业务整合的解决方案之一。SSO定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

单点登录具有身份信息独立管理,更好地使用于分布式管理的优点。但是同时其缺点认证服务器的访问压力较大。

例如:如果引入集群的概念,单应用可能重新部署在3Tomcat以上服务器,使用Nginx来实现反向代理。

但是增加新的服务器之后,不同的服务器之间的Session ID是不一样的,可能在A服务器上登录成功了,能从服务器的Session中获取用户信息,但是在B服务器上却查不到Session信息,只好退出来继续登陆,结果A服务器中的Session因为超时失效,登陆之后又被强制退出来重新要求登陆。

img

所以不得不考虑多服务器之间的session数据一致性的问题,这就是单点登录的最早来源。

单点登录实现的方式

利用Session广播(Session共享)

单点登录的本质就是在多个应用系统中共享登录状态,如果用户的登录状态是记录在session中的,要实现共享登录状态,就要先共享session--利用session广播(session共享)实现

更加具体的解决方案就是使用Redis,就是把原本存储在不同服务器的上的session拿出来放在一个独立的服务器上,之后取用session也从该独立的session服务去取,这样也就实现了session的共享机制。

Cookie+Redis实现

使用cookieRedis实现,要求在项目任何一个服务(模块)进行登录后,把用户数据放到两个地方。一个是cookie,一个是Redis

  • redis中存放包含登录用户信息的键值对(key:value),例如键值key可以采用用户的ID或者登录的IP等,value一般采用用户相关的数据,用户名等等。
  • cookie中则是放入与上述存入redis一致的键值。
  • 逻辑:

当用户在其中一个服务(模块)中登录后,在rediscookie都有相关数据,当用户访问另一服务时,发送的请求会携带登录后存在的cookie,服务通过cookie值到redis中进行查询得到数据,说明该用户已经登录,如果未查到则可以跳转到登录页面。

使用Token实现

https://github.com/bearbrick0/SpringSecurityOauth2_demo

img

  1. 客户端使用用户名跟着密码请求登录。
  2. 服务端收到请求,去验证用户名与密码。
  3. 验证成功后,服务端会签发一个Token,在把这个Token发送给客户端。
  4. 客户端收到Token以后可以把它存储起来,比如放在Cookie里。
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的Token,如果验证成功,就向客户端返回请求的数据。

https://www.jianshu.com/p/3943e9fd3cca

https://www.jianshu.com/p/007f61e925df

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值