php单点登录之模拟淘宝天猫同步登录


说到单点登录大家都很了解,一个站点登录其他域会自动登录。

单点登录SSO(Single Sign On)的方法有很多,比如:p3p、共享session、共享cookice、第三方OAuth认证。

这里模拟淘宝、天猫登录。是模拟噢,要做到安全就要进行很多安全验证RSA加密了,带签名的参数了等。

淘宝与天猫登录时都是在淘宝登录,登录后redirect跳转到各自的网站HTTP_REFERER。

本地模拟,MY淘宝:http://my-taobao.com:8080/      My天猫:http://my-tmall.com/

为什么本地模拟的时候要修改一个的默认端口80为8080或其他端口,参考:http://www.cnblogs.com/dcb3688/p/4608003.html

My淘宝有三个文件,分别是:index.php login.php 与api.php

index.php

<?php
session_start();
$session_name=  isset($_SESSION['name'])?$_SESSION['name']:'';
$session_token=  isset($_SESSION['token'])?$_SESSION['token']:'';

if($session_name){
     echo "{$session_name}您已登录My-Taobao.com   退出";
}else{
     echo "您还未登录My-Taobao.com   登录";
}

login.php


$_SERVER['HTTP_REFERER'] ?>">
<?php

session_start();
$session = isset($_SESSION['token']) ? $_SESSION['token'] : '';
$redirect = isset($_REQUEST['redirect']) ? $_REQUEST['redirect'] : "/";
$action = isset($_POST['action']) ? $_POST['action'] : '';
/**
 * post 登录
 */
if ($action == 'login') {
    if ($session) {  #已经是登录的状态
        echo '';
    }
    $session = md5(time() . uniqid());
    $_SESSION['token'] = $session;
    $_SESSION['name'] = $_POST['name'];
    $_SESSION['create_time'] = time();

    if (!is_dir('session')) {
        mkdir('session');
    }
    $fopen = fopen('session/' . $_SESSION['token'], 'w+'); //新建文件命令
    fputs($fopen, serialize($_SESSION)); //向文件中写入内容;
    fclose($fopen);

    exit('');
}







/**
 * curl登录验证
 */
if ($action == 'curl_valid') {
    $token = isset($_POST['token']) ? $_POST['token'] : '';
    $res = 0;
    if ($token) {
        if (file_exists('session/' . $token)) { # 存在该文件
            $data = unserialize(file_get_contents('session/' . $token));
            if (isset($data['create_time'])) {
                if ($data['create_time'] > time() - 7200) {
                    $res = 1;
                }
            }
        } 
    }
    
    exit( json_encode(["status"=>$res]));
}

/**
 * get 退出
 */
$actionLogout = isset($_GET['action']) ? $_GET['action'] : '';
if ($actionLogout == 'logout') {
    if (isset($_GET['token'])) {
        unlink("session/".$_SESSION['token']);
        unset($_SESSION['token']);
        unset($_SESSION['name']);
    }
    exit('');
}

/**
 * jsonp 访问
 */
$jsonp = isset($_GET['jsonp_callback']) ? $_GET['jsonp_callback'] : '';
if ($jsonp) {
    $status = 0;
    $node = [];
    $msg = '';
    if (isset($_SESSION['token'])) {
        $status = 1;
        $msg = 'success';
        $node = $_SESSION;
    } else {
        $msg = 'fail';
    }
    exit($jsonp . '(' . json_encode(['status' => $status, 'msg' => $msg, 'node' => $node]) . ')');
}

My天猫有两个文件: index.php 与 list.php

index.php






list.php

<?php

$token = isset($_COOKIE["token"]) ? $_COOKIE["token"] : '';
//print_r($token);

$curl = curl(["action" => 'curl_valid', "token" => $token], "http://my-taobao.com:8080/api.php");
$ac = json_decode($curl, TRUE);

if (isset($ac['status']) && $ac['status'] == 1) { # 登录中
    echo '
    ' . '
  • 1111
  • ' . '
  • 2222
  • ' . '
  • 3333
  • ' . '
  • 4444
  • ' . '
  • 5555
  • ' . '
'; } else { echo '已退出'; } function curl($data, $url, $method = 'POST', $headers = array()) { $ch = curl_init(); $method_upper = strtoupper($method); if ($method_upper == 'POST') { curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } else { $url = $url . (strpos($url, '?') ? '&' : '?') . (is_array($data) ? http_build_query($data) : $data); curl_setopt($ch, CURLOPT_URL, $url); } curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method_upper); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //SSL 报错时使用 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //SSL 报错时使用 if ($headers) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } $tmpInfo = curl_exec($ch); if (curl_errno($ch)) { exit(curl_error($ch)); } curl_close($ch); return $tmpInfo; }

很简单的原理,My淘宝是正常网站登录与注销(主站)。当任何一个网站登录且访问My天猫,My天猫就Jsonp请求当前浏览器中是否登录过MY淘宝。如果登录过就种下一个cookice保存MY淘宝sessionKey。

当要访问My天猫其他页面的时候可直接通过获取Cookice使用php的CURL请求网站MY淘宝是否登录。

PHP