IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 简单轻松实现单点登录(sso) -> 正文阅读

[大数据]简单轻松实现单点登录(sso)

前言:

  • 本文虽然使用PHP语言讲单点登录,但是更多讲的是一种实现思想,不仅限于PHP。
  • 该单点登录方案完全实现跨域名。
  • JWT的使用只是生成一个唯一token字符串,也可以不利用JWT。
  • 重要存储Token方式,Cookie与Redis。
  • 支持原创文档。? ? ? ??
  • 该单点登录方案已稳定运用到本人所在公司的项目。
  • 欢迎讨论和提问。

一、WEB程序的“会话机制”

简单回顾:

1.http协议是无状态的

????????是指协议对于交互性场景没有记忆能力,每次请求http都会当做一次新的请求。

2.让服务器有记忆能力之Cookie、Session

????????WEB到底是如何采用Cookie+Session来进行“会话状态”维护的:

  • ?浏览器发起第一次请求,服务器(php)创建一个唯一sessionID
  • ?把sessionID设置到cookie中
  • ?浏览器发送第二次、第N次请求都会携带cookie中的sessionID,服务器去识别是谁在请求?

3.客户端禁用Cookie之后如何使用Session

????????session是基于cookie的,但cookie只是传递一个sessionID,cookie禁用后我们可以利用url传sessionID的方式进行使用session。

4.举例:

????????4.1 创建一个session并且,生成几个跳转其他页面的链接

????????4.2 点链接后跳转的页面,输出session值

????????4.3 演示结果:

? ? ? ? 4.4 要实现禁用cookie,地址栏自动携带sessionID需要改php.ini的相关配置:

在php.ini文件中

1.session.use_trans_sid=1 当浏览器禁止cookie时,页面上的链接会基于url传递SESSIONID

2.session.use_only_cookies=0 表示是否只开启基于cookie的session的会话方式(为1,禁用cookie后,无法使用session)

3.session.use_cookies=1 表示是否开启基于cookie的session会话(如果为0,地址栏有sessionID会默认取地址栏,不优先取cookie中的sessionID)

说明:

当前配置,如果浏览器禁用cookie则会取地址栏的PHPSESSID,浏览器没有禁用cookie则会取cookie中的PHPSESSID。

4.4 为什么跨域名还能访问同一个session?

? ? ? ? 因为我是在自己本地运行的,使用同一个PHP服务。

????????php.ini设置了保存session文件地址

二、单系统登录

????????我们了解了Cookie和Session机制,就可以利用它们做单系统登录。

//账号密码校验成功 在cookie中生成登录标识is_login

setcookie('is_login', true, time() + 1000, '/', 'qq.com');

//浏览器再次访问

if(isset($_COOKIE['is_login']) && $_COOKIE['is_login']) {

echo '已经登录';

} else {

echo '未登录';

}

????????缺点,浏览器出于对Cookie的保护,Cookie无法跨域获取,只能在同源域名下访问。

网址

是否同享cookie

www.a.com

?

admin.a.com

?

test.a.com

?

www.b.com

?

??

三、单点登录

????????1.解决什么问题

????????????????随着公司业务扩展,肯定不止一个系统,如果每个系统都有一套登录逻辑,一个个去登录,难免会很麻烦,单点登录来解决这一问题。

????????2.使用SSO的好处

????????????????方便用户:用户使用系统时,一次登录,就有权访问多个网站,同时也不用牢记多套名称和密码。

????????????????方便管理员:管理员只需要维护一套统一的用户账号。

????????????????简化应用开发:开发新的业务系统时,登录逻辑可以直接对接sso的单点登录,简化开发流程。

????????如下图,每个系统没有独立的登录页面,而是去sso系统登录,如果其中一个系统登录,那么其他系统会自动登录。

????????3.实现思路

????????????????3.1 A系统

????????????????????????1. 用户访问系统A,系统A发现用户未登录(中间件校验局部token是否有效),跳转至sso系统校验全局是否登录,并将自己的地址等作为参数。

????????????????????????2. sso系统发现用户未登录,跳转到sso登录页面。

????????????????????????3. 用户输入账号密码提交登录。

-----------------------ajax请求sso登录接口开始--------------------------------------------------

????????????????????????4. sso登录接口,从数据库验证账号密码是否正确。

????????????????????????5. 拿到用户ID,传入JWT生成加密token

????????????????????????6. 建立全局会话(把token保存到redis、cookie中,并设置有效期 )

$timeout = 3600;//有效时间为1小时

//1.{token:token}格式保存到redis 用于中间件中校验 cookie中的token是否与redis一致

$redis->setex('redis中的全局token' . $token, $timeout, $token);

//2.保存到cookie中 有效期为24小时

setCookies('cookie中的全局token', $token, time() + 3600 * 24, '/');

????????????????????????7. 建立局部会话(curl方式请求A系统创建局部token的方法,并返回局部token)

$url = "http://www.A系统.com/receiveToken";

$params = ['token' => 全局token, 'user_id' => 用户id];

A系统局部token = $this->curlPost($url, $params);

????????????????????????8. sso系统带着局部token,返回ajax请求,js跳转到A系统。

location.href = 'http://www.A系统.com?local_token=A系统局部token';

-----------------------ajax请求sso登录接口结束---------------------------------------------------

????????????????????????9. A系统:

????????????????????????接收地址栏局部local_token 设置cookie中,判断是否登录的中间件中会用cookie中的局部token与redis中的局部token进行比较,校验通过完成登录。

????????流程图:

????????????????3.2 B系统

????????????????????????1. 访问B系统,中间件中会判断cookie中的局部token是否有效(1.是否存在,2.是否与redis中一致)。

????????????????????????2. 局部token无效,则带着B系统回调地址,跳往sso验证全局token的方法。

????????????????????????3. sso系统验证全局token的方法中,校验全局cookie中的token是否有效(1.是否存在,2.是否与redis中的一致)。

????????????????????????4. 全局token有效,则重新生成全局token(设置cookie,redis),并给B系统分配局部token(curl方式请求B系统创建局部token的方法,并返回局部token)。

????????????????????????5. 重定向跳往B系统的回调地址,地址栏并携带局部token。

????????????????????????6. B系统接收sso系统传来的局部token,设置cookie中。

????????????????????????7.中间件校验是否登录,会用cookie中的局部token与redis进行校验。(第4步时已经把局部token保存在B系统的redis中),校验通过完成登录。

????????????????说明:

????????????????????????第4步,全局token有效,但还是重新生成全局token,是等同于重新登录,重新设置过期时间等。

????????3.3 延长登录有效期

????????????????需求场景:

????????????????????????登录成功后,例如登录状态有效期为2小时,如果过了2小时一直没有刷新浏览器(没有新的请求)则登录状态失效,如果中途有访问,则自动延长登录有效期。

????????????????实现方案:

????????????????????????0.前提:登录把sso全局token的cookie设置24小时有效期或不设置有效时间。

????????????????????????1.子系统中间件中,判断局部token在redis中的登录有效期时间,如果小于30分钟,则 curl方式调用SSO系统延长有效期接口。

????????????????????????2.SSO系统延长redis中全局token有效期。

????????????????????????3.之后延长子系统局部redis中token有效期。

????????????????说明:

????????????????????????问题:为什么cookie中的有效期与redis中的不一致?

????????????????????????答:因为为了更好的用户体验,我们只是通过curl方式去延长有效期,不用管cookie,对于用户是无感知的。因为cookie是基于浏览器的,如果需要延长cookie有效期,还得浏览器去跳转。

四、单点注销

????????注销一个系统,同时也注销其他已经登录的系统。

????????思路:

????????????????1.登录SSO、或验证全局登录成功后,给子系统分配局部token时创建redis集合,redis的key为subsystem_url_token_list_+全局token ,值为局部子系统地址及局部token。

$子系统url及子系统局部token = [

????????['callback_url' => 'http://www.A系统.com', 'local_token' => 局部token],

????????['callback_url' => 'http://www.B系统.com', 'local_token' => 局部token],

];

????????????????2.点击注销登录,后端删除当前系统cookie中的token,然后重定向至sso系统退出登录的方法,方法中从cookie中获取全局token,然后从redis集合中获取所有子系统的url和local_token,循环 根据url去各自子系统接收注销的方法,子系统注销登录的方法中会根据local_token删掉子系统redis中的局部token,全部执行成功,再删掉全局redis中的token及cookie中的token。成功后 跳往登录页。(所有子系统中间件会校验cookie中的token是否与redis一致,不一致去校验全局token,全局token失效则跳往登录页,完成注销)

图解:

????????登录成功时记录:

????????注销登录逻辑:

很感谢你耐心看到最后,如果感兴趣或者有任何问题,欢迎你的留言,作者会一一作答。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-05 11:05:11  更:2021-09-05 11:05:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:20:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码