分布式 - CAS 架构实现 SSO 单点登陆
目录
2-3 多域名的 Cookie 跨域问题(暂时未测出跨域,暂留)
一、单点登录概念
Single Sign On(简称SSO),基于分布式系统的概念,在多个系统*用一个登录判断。即,用户在A系统内登陆,操作B系统时,默认用户已经登陆。
二、分布式系统 SSO 实现总结
2-0 单机部署的登陆状态保存
- 用户登录时,验证用户的账户和密码
- 生成一个Token保存在数据库中,将Token写到Cookie中
- 将用户数据保存在Session中
- 请求时都会带上Cookie,检查有没有登录,如果已经登录则放行
2-1 分布式部署的登陆状态保存
在分布式中,仍然延续使用Token来判断登陆状态的key,但是Session却存在着多系统数据无法共享的问题在。
Session 数据共享解决思路:
- 在 Django 内的 Session 默认保存在对应的 django-session 表内,可以对对应的数据库进行集群部署,集群内的表完全同步。【会影响集群的性能呢,不建议】
- 根据请求的 IP 进行 Hash映射 到对应的机器上 ,这就相当于请求的IP一直会访问同一个服务器【如果服务器宕机了,会丢失了一大部分Session的数据,不建议】
- 把 Session 数据放在 Redis 中,使用 Redis 模拟 Session【建议】
- Flask 中 Session默认存储在cookie内,局限性大,但可以使用 flask-session 将数据转移到 Redis 内存储。
2-2 分布式SSO实现
思路总结
- 登陆功能,正常登陆业务流程,登陆成功后生产一串token,并将其写入redis存储(token:{'username':username})
- 其他功能,请求SSO进行登陆,将返回的token写入Cookie中
- 其他功能,对其他接口的正常请求,带上含有token 的Cookie
- 接口接受请求,对携带的token去数据库进行数据获取,若数据无误则通过登陆验证。
登陆验证思路
- 登录验证接口接受请求
- 判断cookie内有无token
- 无,验证不通过,重定向登陆
- 有,取出数据和redis中数据进行校验,无误则通过登陆验证
2-3 多域名的 Cookie 跨域问题(暂时未测出跨域,暂留)
在单域名下,cookie互通,但是在多域情况下,Cookie是隔离的。若多系统的部署在多个不同的域名下,则会导致用户向系统A登录后,系统A返回给浏览器的Cookie,用户再请求系统B的时候不会将系统A的Cookie带过去。
针对Cookie存在跨域问题,有几种解决方案
- 服务端将Cookie写到客户端后,客户端对Cookie进行解析,将Token解析出来,此后请求都把这个Token带上就行了
- 多个域名共享Cookie,在写到客户端的时候设置Cookie的domain。
- 将Token保存在SessionStroage中(不依赖Cookie就没有跨域的问题了)
2-3-0 跨域测试
系统A:127.0.0.1:5000,系统B:127.0.0.1:5001
基于Flask框架的session存储,session存储在cookie内。
系统A接口:api0,login
系统B接口:api1
(api0,api1 都需要session内有指定token值才成功)
系统A测试
- api0无session测试,api0报错
- login 先登陆接口,api0 正常访问
系统B测试
- api1 直接测试报错
- login 先登录,api1 正常访问
结论
- Flask + Postman 测试无跨域隔离。
- Flask + Chrome 测试无跨域隔离
三、基于分布式的SSO实现
3-1 使用中间件实现登陆功能验证
3-2 使用中控机实现sso(推荐)