由于公司的业务较多,所以希望用户在一个域名登陆后,访问公司的其他域名时也保持登陆状态,在网上查找了相关的文档后,使用了如下方案设计:
设计思路:登陆成功时生成一个登陆token,通过这个token可以验证用户状态信息,将token返回,js接收到token后通过iframe转发到其他需要登陆的域名中,其他域名监听message,存在信息并且验证通过后保存之本地当中,访问其他域名时判断存在token,则用token前往获取数据,获取成功则保存为登陆状态,反之则跳转登陆
参考demo如下:
host1:www.host1.com,
在域名下创建index.php,login.php文件
//1、index.php
<?php
session_start();
if(!empty($_SESSION['username']))
{
echo "登录成功:".$_SESSION['username'];
echo "<br/><a href='http://www.host2.com'>host2</a><br/>";
echo "<a href='http://www.host3.com'>host3</a><br/>";
echo "<a href='http://www.host4.com'>host4</a>";
}else{
echo "<a href='/login.php'>请先登录</a>";
}
?>
//2、login.php
<?php
session_start();
//判断是否登陆
if($_SESSION['username']){
header("location:www.host1.com");
exit();
}
$up = $_GET['up'];
if($up){
//验证用户信息,省略
$data = [
'result' => 'abcacbabcbackbaskca',
'code' => 200,
'msg' => 'ok'
];
//保存session
$_SESSION['username'] = 'ganganlee';
echo json_encode($data,256);
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>用户登陆</title>
</head>
<body>
<div>
<label>用户名:</label>
<input type="text" name="username">
</div>
<div>
<label>用户密码:</label>
<input type="password" name="password">
</div>
<button onclick="login()">login</button>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<iframe hidden src="http://www.host2.com/sso.php" id="sso2"></iframe>
<iframe hidden src="http://www.host3.com/sso.php" id="sso3"></iframe>
<iframe hidden src="http://www.host4.com/sso.php" id="sso4"></iframe>
<script type="text/javascript">
function login() {
const username = $('input[name=username]').val();
const password = $('input[name=password]').val();
const up = 'y';
$.get('',{username,password,up},(json)=>{
//登陆成功
document.getElementById("sso2").contentWindow.postMessage(json.result,"http://www.host2.com/sso.php");
document.getElementById("sso3").contentWindow.postMessage(json.result,"http://www.host3.com/sso.php");
document.getElementById("sso4").contentWindow.postMessage(json.result,"http://www.host4.com/sso.php");
window.location.href = '/';
},'json');
}
</script>
</html>
host2:www.host2.com、host3:www.host3.com、host4:www.host4.com、
在域名下创建index.php,login.php,sso.php文件
//index.php
<?php
session_start();
if(isset($_POST['up'])){
//验证token,省略...
$_SESSION['username'] = 'ganganlee';
$data = [
'msg' => 'ok',
'code' => 200,
'result'=>''
];
echo json_encode($data,256);
exit();
}
if(!empty($_SESSION['username']))
{
//这里需要对应域名的链接,不改也没关系
echo "登录成功:".$_SESSION['username'];
echo "<br/><a href='http://www.host1.com'>host1</a><br/>";
echo "<a href='http://www.host2.com'>host2</a><br/>";
echo "<a href='http://www.host4.com'>host4</a>";
}else{
echo "请先登录";
//判断是否存在token
include './login.php';
}
?>
//login.php
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
const token = localStorage.getItem("token");
if(token){
const up = 'y';
$.post("",{up,token},(json)=>{
if(json.code == 200){
console.log(json);
//登陆成功,删除token
localStorage.removeItem("token");
window.location.href = '/';
}
},'json');
}
});
</script>
</html>
//sso.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SSO</title>
</head>
<body>
<h2>监听用户登陆</h2>
</body>
<script type="text/javascript">
//监听发送数据
window.addEventListener('message',function(event){
console.log(event);
localStorage.setItem("token",event.data);
});
</script>
</html>
然后访问www.host1.com进行验证,是有通过host1才能登陆,退出登录同理