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);
}

?>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章