zoukankan      html  css  js  c++  java
  • 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 "<strong>{$session_name}</strong>您已登录My-Taobao.com &nbsp; <a href='/api.php?action=logout&token={$session_token}'>退出</a>";
    }else{
         echo "您还未登录My-Taobao.com &nbsp; <a href='/login.php'>登录</a>";
    }

    login.php

    <meta charset="utf-8"/>
    <form action="api.php" method="post">
        <input type="text" name="name">
        <input type="hidden" name="action" value="login">
        <input type="hidden" name="redirect" value="<?php echo $_SERVER['HTTP_REFERER'] ?>">
        <input type="submit">
    </form>
    <?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 '<meta charset="UTF-8"><script type="text/javascript">window.location.href = "' . $redirect . '";</script>';
        }
        $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('<meta charset="UTF-8"><script type="text/javascript">window.location.href = "' . $redirect . '";</script>');
    }
    
    
    
    
    
    
    
    /**
     * 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('<script type="text/javascript">window.location.href = "' . $_SERVER['HTTP_REFERER'] . '";</script>');
    }
    
    /**
     * 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

    <span id="line">
    
    </span>
    <script src="http://yiiui.com/static/v1/JUI/js/jquery-1.7.2.min.js"></script>
    
    <script >
    
        /**
         * 获取cookie
         */
        function getCookie(cookiename) {
            var result;
            var mycookie = document.cookie;
            var start2 = mycookie.indexOf(cookiename + "=");
            if (start2 > -1) {
                start = mycookie.indexOf("=", start2) + 1;
                var end = mycookie.indexOf(";", start);
    
                if (end == -1) {
                    end = mycookie.length;
                }
                result = unescape(mycookie.substring(start, end));
            }
            return result;
        }
        /**
         * 设置cookie
         */
        function setCookie(name, value) {
            var Days = 30;
            var exp = new Date();
            exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
            document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
        }
    
        var token = getCookie("token");
    
    
        if (token === null) { // 首次访问my-tmall.com
    
            // php curl 不能获取session因为curl是服务器端请求,jsonp是本地的客户端请求。
            $.getJSON("http://my-taobao.com:8080/api.php?jsonp_callback=?", function (data) {
                if (data.status == 1) {
                    data = data.node;
                    setCookie('token', data.token);
                    console.log(data);
                    $("#line").html("<strong>" + data.name + "</strong>您已登录My-Tmall.com &nbsp; <a href='http://my-taobao.com:8080/api.php?action=logout&token=" + data.token + "'>退出 </a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='list.php'>列表</a>");
                } else {
                    $("#line").html("您还未登录My-Tmall.com &nbsp; <a href='http://my-taobao.com:8080/login.php'>登录</a>");
                }
            });
        } else { // 已经登录过,查询现在登录状态
            $.getJSON("http://my-taobao.com:8080/api.php?jsonp_callback=?", function (data) {
                if (data.status == 1) {  // 登录
                    data = data.node;
                    if (data.token != token) {  // 登陆其他账户了
                        setCookie('token', data.token);
                        window.location.href = document.location.href;
                    } else {
                        $("#line").html("<strong>" + data.name + "</strong>您已登录My-Tmall.com &nbsp; <a href='http://my-taobao.com:8080/api.php?action=logout&token=" + data.token + "'>退出</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='list.php'>列表</a>");
                    }
                } else { // 未登录 
                    $("#line").html("您还未登录My-Tmall.com &nbsp; <a href='http://my-taobao.com:8080/login.php'>登录</a>");
                }
            });
        }
    
    
    
    
    </script>

    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 '<ul>'
        . '<li>1111</li>'
        . '<li>2222</li>'
        . '<li>3333</li>'
        . '<li>4444</li>'
        . '<li>5555</li>'
        . '</ul>';
    } 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淘宝是否登录。

  • 相关阅读:
    hadoop中常见的问题
    RedHat中敲sh-copy-id命令报错:-bash: ssh-copy-id: command not found
    【POJ2411】Mondriaan's Dream(轮廓线DP)
    【CF248E】Piglet's Birthday(动态规划)
    【BZOJ2655】Calc(拉格朗日插值,动态规划)
    【Luogu4781】【模板】拉格朗日插值
    【CF995F】Cowmpany Cowmpensation(动态规划,拉格朗日插值)
    拉格朗日插值公式
    求集合中选一个数与当前值进行位运算的max
    【HDU4471】Homework(矩阵快速幂)
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4608024.html
Copyright © 2011-2022 走看看