前后端分离如何做SSO单点登录?

原文在这里: 前后端分离如何做SSO单点登录?
扫一扫加关注【爪哇优太儿】
在前面的文章中单点登录系统SSO是如何实现的?我们实现了一个简单的单点登录,但是那里面有几个问题:一个是全局的token是在url中明文传递的,如果把这个url分享出去,任何人都可以使用这个token,还一个问题,现在的很多系统都是前后端分离的,我们之前介绍的还是传统的服务端渲染方式。本文就来看下如何解决这两个问题。

实现的思路跟之前基本上差不多,我们这次画一个图来看一下:

在这里插入图片描述
1)用户在a.com的某个页面上,访问了后端一个需要登陆的接口的时候,接口首先是从cookie中取token,如果能取到,调用用户中心的接口做验证,验证通过,做业务处理,数据返回给页面。

(2)如果接口没有取到cookie,或者cookie验证失效,这里还是得重定向到用户中心的登录页面,同时要把当前页面的url传递过去,注意这里传递的是页面的url并不是请求的接口的url,因为登陆成功以后要跳转回用户所在的页面。

(3)重定向到用户中心以后,用户中心首先从cookie中取uc.com的cookie,如果能取到并且验证通过,则进入uc的一个proxy页面,这个页面做两件事:一是加载一个a.com的iframe,在a.com上种cookie,二是种完以后,跳转回a.com的url页面上。

(4)如果用户中心取不到uc.om上的cookie或验证失败,则展示登录页面,用户输入用户名和密码做登录,登陆成功以后,写出uc.com的cookie,此时还是进入uc的proxy页面,做同样的事情,通过iframe种a.com的cookie,跳转回a.com。

此时,如果用户在a.com上再发起请求,因为已经有cookie了,直接在a.com上调用用户中心的接口验证就可以了。

整个流程大概就是这个样子,其实也没什么太难以理解的东西,主要是uc.com上通过proxy页面往a.com上种cookie,这样就避免了跳转回a.com上的时候,token在url中明文传递。此时要有个约定:所有的业务域上都必须要有一个能种cookie的proxy页面,供uc.com来调用。我们就重点来看下这两个proxy:

uc.com上的proxy:


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>proxy</title>
</head>
<body>
<input type="hidden" th:value="${user_center_tk}" id="user_center_tk"/>
<input type="hidden" th:value="${redir_url}" id="redir_url"/>
<script>
function createProxyUrl(url){
    var pos = url.indexOf("://");
    var protocal = url.substring(0, pos+3);
    var left = url.substring(pos+3);
    var root = left.indexOf("/")
    var hostPort = "";
    if(root < 0){
        hostPort =left;
    }else{
        hostPort =left.substring(0, left.indexOf("/"));
    }
    return protocal + hostPort + "/proxy.html";
}
var iframe = document.createElement("iframe");
var redirectUrl = document.getElementById("redir_url").value;
var user_center_tk =  document.getElementById("user_center_tk").value;
var proxyUrl = createProxyUrl(redirectUrl);
iframe.src = proxyUrl+"?user_center_tk=" + user_center_tk;
document.getElementsByTagName("body")[0].appendChild(iframe);
iframe.onload=function(){
    window.location.href = redirectUrl;
}
</script>
</body>
</html>

这个是个thymeleaf的模板,登陆成功以后加载这个模板,服务端传到进来2个参数,一个是全局的token,一个是跳转回去的url,通过js动态创建一个iframe,加载业务域上的的一个固定的url,并且传递token参数,虽然也是明文在url中传递,但是,对用户而言是看不到的,跳转回去的时候,地址栏中也不会传递。

a.com上的proxy:


<script>
function getQueryVariable(variable)
{
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    for (var i=0;i<vars.length;i++) {
        var pair = vars[i].split("=");
        if(pair[0] == variable){return pair[1];}
    }
    return(false);
}
var tk = getQueryVariable("user_center_tk");
document.cookie="site1_tk="+tk
</script>

它做的事情就 比较简单了,从url中截取token,写到cookie中就完事了。

总结一下:

(1)cookie不能跨域,uc.com只能写uc.com上的cookie,a.com只能写a.com上的cookie

(2)iframe是可以跨域的,uc.com使用iframe加载a.com上的页面的时候,可以传递参数,a.com收到参数就可以写到cookie中,这样就间接的实现了uc.com到a.com种cookie。

完整的源码在:https://github.com/xjs1919/enumdemo下面的sso-static,实验环境与上一篇单点登录系统SSO是如何实现的?相同。

如果感觉对你有用,欢迎扫描文章开头的二维码加关注:
在这里插入图片描述

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值