PHP实现单点登录认证中心

1.单点登录基本过程

1.1应用第一次登录

应用 认证中心 重定向到认证中心 表单登录验证 返回token 使用token获取用户信息,登录成功 应用 认证中心

1.2其他应用第二次登录

应用 认证中心 重定向到认证中心 无需登录直接返回token 使用token获取用户信息,登录成功 应用 认证中心

1.3退出登录

应用 认证中心 清除session 重定向到认证中心 清除session重定向到应用 应用 认证中心

2.部分代码

2.1应用端

//返回token
if(isset($_GET['token'])){
    $result= file_get_contents('http://ids.domain.net/check.php?token ='.$_GET['token']);
    $result=json_decode($result,TRUE);
    if($result['success']){
        $_SESSION['logged']=$result['user'];
        header('Location: http://app.domain.net',true,302);
    }else{
        header('Location: http://app.domain.net',true,302);
    }
    exit;
}
//第一次打开
if ( ! isset($_SESSION['logged'])) {
    header('Location: http://ids.domain.net?service=http://app.domain.net',true,302);
    exit;
}
//登录成功后的逻辑

2.2认证中心

$user_info=[
    "user1" => "password1",
    "user2" => "password2",
];

session_start();
//退出
if(isset($_GET['action'])){
    $action=$_GET['action'];
    if($action == 'logout'){
        unset($_SESSION['user']);
        if(isset($_GET['service'])){
            header('Location: '.$_GET['service'],true,302);
            exit;
        }
        header('Location: /',true,302);
        exit;
    }
}

if(isset($_SESSION['user'])){
    show_logined();
    exit;
}

if(isset($_POST['login'])){
    $username=trim($_POST['username']);
    $password=trim($_POST['password']);
    if(($username == '')||($password == '')){
        reshow_loginfo('用户名或密码不能为空');
        exit;
    }
    $logined=false;
    foreach($user_info as $k=>$v){
        if($username == $k && $password == $v){
            $logined=true;
        }
    }
    if($logined){
        $_SESSION['user']=$username;
        //登录成功
        if(isset($_GET['service'])){
            header('Location: /?service='.$_GET['service'],true,302);
        }else{
            header('Location: /',true,302);
        }
        exit;
    }else{
        reshow_loginfo('用户名或密码错误');
        exit;
    }
}

reshow_loginfo('');

function reshow_loginfo($info){
?>
<html>
<head>
<title>统一身份认证</title>
</head>
<body>
<p><font color="#e32"><?php echo $info; ?></font></p>
<form action="<?php
if(isset($_GET['service'])){
    echo "/?service=".$_GET['service'];
}else{
    echo "/";
}
?>" method="post">
    <input type="hidden" name="login" value="login"/>
    <input type="text" name="username" class="text" value="<?php echo $_POST['username'] ?>" placeholder="用户名" >
    <input type="password" name="password" value="" placeholder="密码" >
    <input type="submit"  value="登录" >
</form>
</body>
</html>

<?php
}
function show_logined(){
//已经登录
if(isset($_GET['service'])){
    $token=uuid();
    $redis = new redis();
    $redis->connect('127.0.0.1', 6379);
    $redis->set($token,$_SESSION['user']);
    $redis->expire($token,180);
    header('Location: '.$_GET['service'].'?token='.$token,true,302);
    exit;
}
?>
<html>
<head>
<title>登录管理</title>
</head>
<body>
<h2>欢迎<?php echo $_SESSION['user'] ?></h2>
<a href="/?action=logout" class="logout">退出</a>
</body>
</html>
<?php
}
function uuid($prefix = '')
{
    $chars = md5(uniqid(mt_rand(), true));
    $uuid  = substr($chars,0,8) . '-';
    $uuid .= substr($chars,8,4) . '-';
    $uuid .= substr($chars,12,4) . '-';
    $uuid .= substr($chars,16,4) . '-';
    $uuid .= substr($chars,20,12);
    return $prefix . $uuid;
}

2.3验证token

<?php
header('Content-Type: application/json; charset=utf-8');
$result=[
    'success'=>false,
    'reason'=>null,
    'user'=>null,
];
if( ! isset($_GET['token'])){
    $result['reason']='no token';
    echo json_encode($result);
    exit;
}
$token=$_GET['token'];
$redis= new redis();
$redis->connect('127.0.0.1',6379);
$user=$redis->get($token);
if($user != null){
    $result['success']=true;
    $result['user']=$user;
    echo json_encode($result);
}else{
    $result['reason']='null user';
    echo json_encode($result);
}

?>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值