文章插图
需求多个应用系统中 , 用户只需要登录一次就可以访问所有相互信任的应用系统 。
A 网站和 B 网站是同一家公司的关联服务 。现在要求 , 用户只要在其中一个网站登录 , 再访问另一个网站就会自动登录 , 请问怎么实现?
涉及到的关键点:
这里就涉及到了 跨域认证 以及 前端页面 JAVAScript 跨域 问题 。
一、跨域认证问题互联网服务离不开用户认证 。一般流程是下面这样 。
- 用户向服务器发送账户和密码
- 服务器验证通过后 , 在当前会话 (session)里保存相关数据 , 如用户角色、用户ID等
- 服务器向用户返回一个 session_id , 写入用户 cookie
- 用户之后的每一次请求 , 都会通过 Cookie 将 session_id 传回服务器
- 服务器收到 session_id , 找到之前存储的数据 , 由此得知用户身份
方案一: session 持久化
? 将 session 数据持久化 , 写入数据库或别的持久层 。各种服务受到请求后 , 都向持久层请求数据 。
这种方案 , 对于各种系统的代码改动量少 , 只要在权限验证的地方进行判断即可 。
- A 登录成功代码
- 登录成功后 , 将 session 存储到 redis 持久化存储 , 注意设置有效期
- tip:
Redis 以层级形式、目录形式保存数据 , 最大四级 , 格式如下:/** * 将 Session 存储到 Redis * @param boolean $logout 是否退出登陆 默认否 * @return array */public function sessionToRedis($logout = false) { try { if ($logout) { (new Redis())->del('Admin:session:' . session_id()); }else{ $userInfo = session('CH_ADMIN_LOGIN_STATUS'); $res = (new Redis())->setex('Admin:session:' . session_id(), 28800, json_encode($userInfo, JSON_UNESCAPED_UNICODE)); if ($res === false) throw new Exception('Redis 存储失败'); return true; } } catch (Exception $e) { return false; } } </pre>
set('dir:dir:dir:key', 'value');
- 登录成功后 访问 B, B 进行用户身份认证
- 注意 此时 访问 B的链接URL 要携带参数 sessionid!
- B 在处理请求- 身份验证时 , 先解析是否携带了sessionid参数 , 携带了则向 redis 中查询相关数据 , 并将数据保存到当前会话中 。此时就成功 登录 B 了 。
服务器索性不保存 session 数据了 , 「用户数据」加密保存到「客户端」 , 每次请求都将数据发回服务器 , 服务器再进行解析得到用户身份信息数据 。JWT 就是这种方案的一个代表 。
【Single Sign On 单点登录解决方案】JWT 原理
推荐阅读
- 签名 App Sign认证-token签名认证
- 开直播需要哪些设备,简单点 淘宝开直播用什么软件
- 罗技|多型号契合所有用户!罗技Signature M650鼠标今日上线:售价249元
- 肯德基|肯德基中国上新北京炸酱面:单点26元
- 德国IF设计大奖|再创佳绩|箭牌卫浴斩获IF Design award 2021产品设计金奖!
- 马斯克不满WhatsApp新政策 Signal或成最大赢家
- 乔厅:一贯坚持的简约设计,并不简单|Hi-Design金奖作品| a2977
- 肖军:用开放的心态做更年轻的设计|Hi-Designer| a8345
- 沈正全:品牌x设计,让空间与众不“童”|Hi-Design金奖作品| a3509
- fragment|fragment design x Playboy 联名系列释出!