php单点登录SSO(Single Sign On)的解决思路

一、什么是单点登录

解释:登录一个系统后,其它系统无需再次登录,即可进入。

二、举个例子:

你登录了淘宝,然后你进入天猫,发现你不用登录了。这时你要注意到,淘宝跟天猫可是完全不一样的域名。

你登录淘宝后,你的浏览器得到了cookie,但是这个cookie是在淘宝域名下的。你的天猫域名下并没有cookie。

这个时候你要想办法让天猫域名下也有这个相同的cookie。假设你的天猫域名下也有这个cookie。

当你的浏览器进入天猫时,你的浏览器会携带天猫域名下的cookie去服务器验证。

但是这个cookie对应的可是淘宝域名下的session数据,这个时候又该如何呢。

从这个例子中引出两个问题:

1、跨域种cookie

2、服务端保持cookie对应的session数据是一样的

三、解决思路

四、示例代码

A域名下的 index.php 文件

<?php
    header("Content-type: text/html; charset=utf-8");

    if(!empty($_POST)) {
        $response = curl_post('http://www.U.com/index.php',$_POST);
        if($response['code'] > 0) {
            die('error:'.$response['msg']);
        }

        set_cookie('SID',$response['data']['sid'],0,'/','',0,1);
        echo '登录成功';
        $url = 'http://www.B.com/setcookie.php?sid='.$response['data']['sid'];
        die('<script type="text/javascript" src="'.$url.'" reload="1"></script>');

    }

    function curl_post( $url , $arrPost = array() , $func = "http_build_query" ){
        $ch = curl_init();

        $opt[CURLOPT_URL] = $url;
        $opt[CURLOPT_RETURNTRANSFER] = 1;
        $opt[CURLOPT_TIMEOUT] = 10;
        if( !empty( $arrPost ) ){
            if( $func == 'json_encode' )
                $opt[CURLOPT_HTTPHEADER] = array("Content-Type: application/json;charset=UTF-8");
            $opt[CURLOPT_POST] = 1;
            $opt[CURLOPT_POSTFIELDS] = call_user_func( $func , $arrPost );
        }

        curl_setopt_array ( $ch, $opt );
        $response = curl_exec( $ch );
        curl_close( $ch );

        return json_decode($response, true);
    }
    /**
     * 免刷新写入cookie
     * name     必需。规定 cookie 的名称。
     * value     必需。规定 cookie 的值。
     * expire     必需。规定 cookie 的有效期。
     * path     可选。规定 cookie 的服务器路径。
     * domain     可选。规定 cookie 的域名。
     * secure     可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
     * httponly 可选。规定是否禁止js读取cookie。
     */
    function set_cookie($name,$value='',$expire=0,$path='/',$domain='',$secure=0,$httponly=0) {
        $_COOKIE[$name] = $value;
        if(is_array($value)){
            foreach($value as $k=>$v){
                if(is_array($v)){
                    foreach($v as $a=>$b){
                        setcookie($name.'['.$k.']['.$a.']',$b,$expire,$path,$domain,$secure,$httponly);
                    }
                }else{
                    setcookie($name.'['.$k.']',$v,$expire,$path,$domain,$secure,$httponly);
                }
            }
        }else{
            setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
        }
    }
?>
<!DOCTYPE HTML>
<html>
    <head>
        <title>A域名的登录框</title> 
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
        <form action="http://www.A.com/index.php" method="post">
            <input type="text" name="uname" placeholder="帐号"/>
            <input type="password" name="upasswd" placeholder="密码"/>
            <input type="submit" value="提交" />
        </form>
    </body>
</html>

B域名下的 index.php 文件

<?php
header("Content-type: text/html; charset=utf-8");
$sid = isset($_COOKIE['SID']) ? $_COOKIE['SID'] : '';

if(empty($sid)) echo "请先登录";

$response = curl_post('http://www.U.com/index.php',array('sid'=>$sid));
if($response['code'] > 0) {
    die('error:'.$response['msg']);
}

die('您的帐号密码是:'.$response['data']['uinfo']);

function curl_post( $url , $arrPost = array() , $func = "http_build_query" ){
    $ch = curl_init();

    $opt[CURLOPT_URL] = $url;
    $opt[CURLOPT_RETURNTRANSFER] = 1;
    $opt[CURLOPT_TIMEOUT] = 10;
    if( !empty( $arrPost ) ){
        if( $func == 'json_encode' )
            $opt[CURLOPT_HTTPHEADER] = array("Content-Type: application/json;charset=UTF-8");
        $opt[CURLOPT_POST] = 1;
        $opt[CURLOPT_POSTFIELDS] = call_user_func( $func , $arrPost );
    }

    curl_setopt_array ( $ch, $opt );
    $response = curl_exec( $ch );
    curl_close( $ch );

    return json_decode($response, true);
}

B域名下的 setcookie.php 文件

<?php
header("Content-type: text/html; charset=utf-8");
$sid = isset($_GET['sid']) ? $_GET['sid'] : '';

if(!empty($sid)) {
    set_cookie('SID',$sid,0,'/','',0,1);
}

/**
 * 免刷新写入cookie
 * name     必需。规定 cookie 的名称。
 * value     必需。规定 cookie 的值。
 * expire     必需。规定 cookie 的有效期。
 * path     可选。规定 cookie 的服务器路径。
 * domain     可选。规定 cookie 的域名。
 * secure     可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
 * httponly 可选。规定是否禁止js读取cookie。
 */
function set_cookie($name,$value='',$expire=0,$path='/',$domain='',$secure=0,$httponly=0) {
    $_COOKIE[$name] = $value;
    if(is_array($value)){
        foreach($value as $k=>$v){
            if(is_array($v)){
                foreach($v as $a=>$b){
                    setcookie($name.'['.$k.']['.$a.']',$b,$expire,$path,$domain,$secure,$httponly);
                }
            }else{
                setcookie($name.'['.$k.']',$v,$expire,$path,$domain,$secure,$httponly);
            }
        }
    }else{
        setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
    }
}

U域名下的 index.php 文件

<?php
header("Content-type: text/html; charset=utf-8");

$sid = isset($_POST['sid']) ? $_POST['sid'] : '';
if(!empty($sid)) {
    $uname_upasswd = file_get_contents($sid);
    if(empty($uname_upasswd)) {
        die(json_encode(array(
            'code'=>1,
            'msg'=>'fail',
            'data'=>array()
        )));
    }
    die(json_encode(array(
        'code'=>0,
        'msg'=>'success',
        'data'=>array('uinfo'=>$uname_upasswd)
    )));
}

$uname = isset($_POST['uname']) ? $_POST['uname'] : '';
$upasswd = isset($_POST['upasswd']) ? $_POST['upasswd'] : '';
if($uname == '' || $upasswd == '') {
    die(json_encode(array(
        'code'=>1,
        'msg'=>'fail',
        'data'=>array()
    )));
}

define('SID_SALT', '密码盐');

$passwd = passwd($uname.$upasswd,SID_SALT);
file_put_contents($passwd, $uname.','.$upasswd);

die(json_encode(array(
    'code'=>0,
    'msg'=>'success',
    'data'=>array('sid'=>$passwd)
)));


function passwd($string,$salt) {
    return md5(substr(md5($string).md5($salt),16,48));
}

验证流程:

1、进入A域名,输入帐号密码点击登录。

2、进入B域名,此时会打印出你在A域名输入的帐号密码。

注意:这只是一个简单的验证,实际开发中需要做cookie加密,实效验证等。而且,其实单点登录问题,还有其他解决思路。

 

转载于:https://www.cnblogs.com/buexplain/p/4918966.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值