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

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

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

c2989d23423060e110da1697ffc0ae44.png

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

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

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

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

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

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

http://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中传递,但是,对用户而言是看不到的,跳转回去的时候,地址栏中也不会传递。

http://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不能跨域,http://uc.com只能写http://uc.com上的cookie,http://a.com只能写http://a.com上的cookie

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

完整的源码在:https://github.com/xjs1919/enumdemo下面的sso-static。

实验环境与上一篇https://mp.weixin.qq.com/s/dMfi7waQjhp4PFi4fxl_MQ相同。

原文在这里:https://mp.weixin.qq.com/s/uncSGOtTDknqbnezlC-ccg

如果感觉有用,欢迎关注公众号:

c1e44649fb53a3ed931185fc9a5f611d.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值