多域名实现单点登录详解

Hi I’m Shendi


多域名实现单点登录详解




简介

在很久以前给自己的网站制作了登录系统,但因为个人备案等原因没有需要用到登录的地方,于是就没有特意去完善这部分功能,仅仅是将用户部分抽取出来作为一个微服务

最近编写一个转换工具,调后端接口,为了避免被恶意调用,除了使用验证码外,还需要登录才能使用

因为是微服务,项目是多个,为了保证良好的体验,于是将单项目登录更改为单点登录

因为这部分我没有做过,于是首先从网络上查阅相关信息来借鉴,在我n次搜索尝试后,终于放弃了,大抵都是废话一大片,甚至还有的在误导他人,比如不同域名之间使用session做单点登录…毫无收获,只能自己琢磨,于是在这里记录下来



单点登录(SSO)

传统登录在一个项目登录后,在另一个项目状态是未登录,而单点登录是在一个项目登录,所有项目都为登录

例如有两个项目,a.com 与 b.com

用户在 a.com 登陆后,直接访问 b.com,b.com的状态也是登录


可以进入我的网站体验一下效果

目前我自己尝试在一个项目登陆后其他项目也都登录,一个项目退出登陆后所有项目都退出登录,如果发现bug可以通过发送email至[email protected]提醒我一下~

  • sdpro.top
  • tool.sdpro.top


思路

在之前,我是通过点击按钮的方式切换项目登录,这种方式不是单点登录,但可以在项目跳到另一个项目时保持登录状态

后面我思来想去发现要实现单点登录只能使用中间页的方式,主要重心在前端的存储数据部分,只要能够多个项目可以共享登录数据,那就实现了单点登录了


对于浏览器来说,存储数据大致只有 cookie,storage


如果将多个项目都放在一个域名下的话(单域名),那可以使用cookie,和传统登录没啥太大的区别

一个域名的子域名貌似也能共享Cookie,不过对我来说,我已经弃用了cookie(因为有的小程序不支持cookie),使用的Token,于是只能使用 storage,而localstorage的作用域是在当前域名,域名不一致就拿不到数据。

于是制作一个页面作为中间页,将登陆注册操作都放到这个页面。

那么如何判断是否登录?这就需要做很多操作,其他项目的页面在一开始要跳到中间页,在中间页内判断是否登陆,登录就传递一些信息回去…

最开始我想到的是使用iframe,因为iframe可以使用parent来修改父窗口的内容,在iframe加载中间页,是登录的话调用父窗口的某函数或更改属性值告诉父窗口状态为登陆…但经过尝试,这样只能在域名相同的情况下使用,域名不同就会爆跨域

最后只能使用重定向的方式,重定向传递参数只能通过url传递…

总的来说就是通过一个中间页存储登录信息,其余项目通过中间页来获取登录信息

这里画一个简陋的图来描述一下意思

在这里插入图片描述


其中用户微服务与中间页相当于中央认证系统CAS(Center Authentication Service)



实现

为了确定可行性,我首先制作了个demo示例,两个页面放在不同域名下,主要是前端不同项目之间的数据共享实现

项目页面(url包含info代表已登录,未登录跳中间页)

<html>
<body>
    wqeqweqwe
<script>
    if (location.href.indexOf("info") != -1) {
      
      
        console.log("已登录");
    } else {
      
      
        location.href = "中间页?url=" + location.href;
    }
</script>
</body>
</html>

中间页

<html>
<body>
<script>
    location.href = location.href.substring(location.href.indexOf("url=")+4,location.href.length) + "?info=123";
</script>
</body>
</html>

浏览器打开尝试后效果还算可以,剩下的就是逻辑部分了,这里直接做总结了

用户微服务(后端)

  • 使用token,用户登录/注册后拿到token,后续操作携带token则可通过登录验证
  • 提供登录/注册/登出接口等

项目页

  • 首先判断本地是否有登录信息

    • 代表已登录(有可能登陆超时等,这个需要自行去处理,例如记录创建时间,超过就代表失效,或请求后端后端告知登陆已失效…,失效就跳中间页)
    • 携带当前页面地址跳中间页面(这个是必须的),还可以传递更多信息,例如清除登录信息之类的
  • 退出登录同样跳中间页,携带格外的参数通知即可


中间页

  • 本地是否有登录信息,登录信息是否超时/失效
  • 登陆有效
    • 携带登录信息重定向传递的页面地址参数
  • 登陆无效
    • 停留本页作为登录页面或带代表登陆无效的参数重定向回去

注意事项

因为是重定向,url链接长度有大小限制,不同浏览器限制不同,大概是2000多字符,所以如果数据很多的话,可以将数据存到后端,后端返回标识然后在后端拿到数据




最后,有一点不好的就是浏览器的url部分会跳来跳去的,但不关注url的话是无感刷新的




END

猜你喜欢

转载自blog.csdn.net/qq_41806966/article/details/131272287