探究Cookie如何实现单点登录?

兄弟萌,单点登录(SSO)这个概念或许大家并不陌生,但我想有些兄弟还是没搞清楚什么叫做单点登录,下面我们先来介绍一下什么是单点登录?

单点登录(SSO):用户的一次登录能够得到其它所有系统的信任,便可在其它所有系统中得到授权而无需再次登录

这个概念理解起来似懂非懂,下面直接用几张图来让大家理解:

  1. 登录京东首页,会看到有登录按钮,我们点击它可以登录,登录成功后会返回发起登录请求的这个页面
    在这里插入图片描述

  2. 我先不登录,我直接点击一个商品浏览,上方还是有登录按钮
    在这里插入图片描述

  3. 如果我们在商品详情页面登录后,切换到首页刷新一下发现也已经登录了

1.单点登录流程

到这里,想必大家了解了什么是单点登录,下面我们说一说单点登录的流程:

在其中一个子系统登录,跳转到登录系统,登录系统完成登录,完成登录后向发起登录的子系统写入一个 cookie,保存用于认证用户是否登录的信息,其它的子系统要能访问到这个 cookie,在其它子系统向服务器发起请求的时候,携带这个 cookie 完成登录。

注意:只有主域名相同,浏览器在访问时才会携带对应的 cookie

大家留意一下刚才访问京东首页和商品详情页面时,它的主域名是:jd.com。

2.实现单点登录

在这里插入图片描述

  1. 在每个子系统上添加一个登录按钮,能够跳转到登录页面,如:在 www.codeshop.com 和 vip.codeshop.com 中 html 首页添加登录按钮
  2. 在 www.codeshop.com 中点击登录,被拦截器拦截,检查登陆凭证,由于是首次登陆,凭证为空,直接请求服务器
  3. 输入用户名、密码、验证码登录后,在服务器端生成 cookie,并把这个 cookie 响应给前端,同时将这个 cookie + 用户信息封装成一个登录凭证保存在 MySQL 数据库中
String token = UUID.randomUUID().toString();
Cookie cookie = new Cookie("token",token);
//cookie 要在子系统间互相访问的话,它们的域要相同
cookie.setDomain("codeshop.com");
response.addCookie(cookie);
  1. www.codeshop.com 子系统登录成功后,在 vip.codeshop.com 子系统刷新页面,它会带着 cookie 去请求服务器,被拦截器拦截到,检查登陆凭证,去 MySQL 中查找是否有这个 cookie,如果数据库中有,直接返回用户信息,无需登录,如果没有拦截器直接放行,页面无变化。

到这里,我们就简单的实现了单点登录,当然,实现单点登录肯定不止 Cookie 这种方式,实际上使用 Cookie,它是保存在客户端上,如果被窃取或用户禁用了 Cookie,那么就失效了 。我们这里来想一下其它实现方式。

3.实现单点登录的其它方案

  • 如果项目用户量少且不是分布式项目,追求简单可以使用 Session 实现单点登录,但如果在分布式系统中我们还要考虑解决 Session 共享问题,比较麻烦。
  • 考虑使用 Redis + Token 来实现单点登录
  1. 客户端去请求服务器端
  2. 服务器端收到请求后,验证用户名和密码,验证成功后,服务器端生成 Token 令牌(简单理解为生成一段不重复的字符串),将 Token 作为 key,user 作为 value 存放在 Redis 中,同时把这个 Token 令牌响应给客户端
  3. 客户端收到 Token 令牌,使用 localStorage 把它存放在请求头中,客户端每次向服务器发送请求时,都要携带这个 Token
  4. 服务端拦截器进行 Token 校验(去 Redis 中查找是否有对应的令牌),如果是登录状态就放行,未登录就跳转到登录页面
  5. 用户注销时,将存放在 Redis 中的令牌删除,同时把前端保存在 localStorage 中的令牌删掉,避免浪费内存
    在这里插入图片描述

此外,我还想再谈一下跨域的问题,我们要知道浏览器默认情况下无法主动跨域向后端发送 cookie,需要在前端请求时加入配置项 {withCredentials:true},当然在本篇文章的代码中我们手动添加了 cookie.setDomain(“codeshop.com”),所以本篇文章中不用考虑前端向后端跨域发送 cookie 的问题。

两个域之间是不是存在跨域问题,主要是根据协议、域名、端口号这三个点进行判断,只要有一个不一样就是跨域。例如:

  1. 协议不同:http://www.baidu.com 与 https://www.baidu.com
  2. 域名不同:http://www.baidu.com 与 http://www.google.com
  3. 端口号不同: http://www.baidu.com:8080 与 http://www.baidu.com:8000
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值