前端单点登录的笔记

291 阅读4分钟

前言

这里主要记录阐述了我们针对 SAAS、OP端,不同domain登录,第三方登录的解决方案,核心知识点是跨域读cookie,概念类的就不过多阐述了。

先来点凉菜

(账户中心:account.a.com/login) 用于账户的管理和认证,建议作为一个单独项目去开发
1.登录
(支持普通登录和临时令牌,临时令牌为一次性交换真实token的key)

2.登出

3.注册

4.忘记密码

5.跨域登录iframe嵌套
(登录表单的抽离封装,针对iframe作postMessage处理)

6.中转页面
(用于第三方登录,调用接口把url参数全部传给后端处理逻辑,如是否手动跳转,跳转地址,当前html 设置cookie等)

另:根据产品增加各种主题色等等

classDiagram
Account <|-- self_same_domain_App
Account <|-- self_dif_domain_App
Account <|-- out_App
Account : 账户中心
Account :login()
class self_same_domain_App{
与账户中心同domain产品
login()
}
class self_dif_domain_App{
与账户中心不同domain产品
run()
}
class out_App{
第三方中转页面
redirect()
}

重点说下登录接口的Response Headers

p3p: CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'

set-cookie: token=xxx; Path=/; Domain=a.com; Expires=some time; Secure;HttpOnly; SameSite=None

以上就是登录时调用的登录接口,登录状态放在了cookie。HttpOnly纯由后端去控制
临时令牌模式data里返回一个一次性的令牌key

p3p固定写法,查了资料发现这玩意是为了兼容ie浏览器

Secure; SameSite=None 是https时兼容chrom的跨域读cookie 如果你没有不同domian登录的场景可以不加

主菜(拿天猫举个例子)

同domain

cookie是共享的,登录状态是保持
也有些特殊场景,比如我们有其他环境,和线上环境同domain,比如x.a.comy.a.com 我们就可以约束token的key为x_token和y_token,让后端自己去找对应的key去校验token的值

不同domain跨域读cookie (www.b.com)

image.png 页面html的heard

<script type="text/javascript" src="account.a.com/账户中心前端网关/ap…" />

src是后端的一个接口地址 后端可以拿到a.com的cookie信息并且返回js
如var info={'token':'xxx','userId’:’xxx,’username':'xxx'};window.run&& window.run(); image.png

ps:这时候你在控制台看到的其他域的cookie 然后这些并不能通过代码去获取到,而且根据该域cookie状态即时更新

b.com(www.b.com)的登录

image.png 登录iframe嵌套

由于safari浏览器不支持跨域读cookie 包括天猫现在也没做兼容
需要针对浏览器分开处理

非safari 接受postMessage登录成功后走业务跳转,编写上述的run设置 登录状态

safari需要把iframe的src url传入的临时令牌模式,postMessage登录成功后获取临时令牌通过b的后端向a的后端换取真实token并返回设置在cookie上

const init = () => {
  // 监听接收
  window.addEventListener('message', async function (e) {
    const { action, info } = e.data;
    switch (action) {
      // 跳转
      case 'redirect':
        break;
      case 'button':
        break;
      case 'login':
        if (isSafari) {
        } else {
        }
        break;
      //   本地调试设置cookie
      case 'localhost':
        break;
      //  获取href
      case 'getTopUrl':
        if (ref.current) {
          ref.current.contentWindow?.postMessage(
            { action: 'getTopUrl', info: { msg: window.location.href } },
            '*',
          );
        }
        break;
      default:
    }
  });
};

饭后甜点

登出

用a标签后端写个get请求的二次跳转 接受前端的重定向地址和默认重定向

如: https://账户中心地址/登出网关/xx?redirect=xxxx

环境部署是否为http(s)?

1.账户中心: 如果有非同域产品单点登录 则必须为https

2.同域产品(与账户中心domain相同):与 该环境 账户中心 保持一致 

3.非同域产品: http(s)都可 

方案a: sso单点登录,相关的账户中心一定为https 

方案b: 用临时票据ticket调用,相关的账户中心http(s)都可 

中转页面的应用

场景:SAAS第三方登录,OP环境同步登录

拿我们的举个例子,前端的环境变量consif.json

中转地址内逻辑:
config.json:
environment:"OP",
OPLoginConfig.enabledRedirect:true

场景:使用客户登录->票据(ticket或者cookie)->后端控制跳转(去登录或者设置cookie进入页面)

1.校验配置项

2.读配置:OPLoginApiUrl >> 请求接口 >> 处理参数

返回值:

a. error走后端公共抛错 

b. 接口返回Data为参数:

manualHandler:booble 选填,当为true时手动模式,不进行跳转

html:string 选填,替换当前页面html,配合manualHandler使用

redirect:选填,重定向的产品地址 undefined =>默认跳转'/', ("url 地址") => 绝对路径或url,地址需encodeURIComponent 转码

其他key会以url参数形式跟随跳转