• php+ajax实现跨域单点登录


    之前我们在《SSO单点登录三种情况的实现方式详解》中介绍过跨域单点登录的原理。这里向大家介绍利用php和ajax具体实现单点登录。

    在本次示例中我们需要两个站点:

    www.onmpw.com
    www.onmpw1.com

    当然还有一个验证系统

    www.SSOsite.com

    为了实现单点登录。首先,我们需要将要设置两个站点使其共享session。至于如何共享session,可以参考《PHP集群session共享》这篇文章。这里我们就不做详细的介绍了。

    假设我们已经设置了二者可以共享session了。下面我们就来介绍具体实现的流程。

    第一部分

    下面我们用文字来描述该过程

    ·浏览器请求onmpw的需要验证的页面。

    ·通过ajax请求SSOsite系统,查看是否存在SSOsite站点的cookie信息,如果不存在则通知浏览器需要进行登录。

    ·浏览器接收到需要登录的信息后请求onmpw的登录页面(当然有的系统是统一使用SSOsite的登录系统,那就需要浏览器再去请求SSOsite的登录页面了)。

    ·提交登录信息到onmpw系统。onmpw系统通过curl技术将登录信息发送给SSOsite系统进行验证。

    curl_setopt($ch, CURLOPT_URL, "www.SSOsite.com/?c=Auth&a=authUser");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, array('username'=>$username,'password'=>$password));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    $res = json_decode($data);

    ·SSOsite验证成功以后,生成token,并将用户信息连同生成的token一并返回给onmpw系统。

    const chars = 'abcdefgABCDEFG012hijklmnHIJKLMN3456opqrstOPQRST789UVWXYZuvwxyz';
    static public function str_random(){
         //随机生成token串
         $chars = self::chars;
         $token = '';
         for($i = 0; $i < 5; $i++){
            $str = substr($chars,0,mt_rand(0, strlen($chars)-1));
            $token .= $str.$chars[mt_rand(0, strlen($str)-1)];
         }
         $token = md5($token);
         return $token;
     }

    ·onmpw接收到SSOsite返回的验证成功的信息以后,将用户信息写入浏览器的cookie中。最后将登录成功的信息响应给浏览器。

    setcookie('userid',$res->userid,null,'/');    //设置本站点cookie

    ·然后浏览器再次通过ajax将得到的token发送给SSOsite。

    checkToken:function(args){
             $.ajax({
                       url:Onmpw_SSO.Configure.SSO_Server+'/?c=Auth&a=checkToken',
                       xhrFields: {withCredentials: Onmpw_SSO.Configure.Cross_Domain},
                       dataType:'json',
                       type:'post',
                       data:{token:args.token,userid:args.userid},
                       success:function(data){
                                args.Suc();
                       },
                       error:function(err){
                                console.log(err);
                       }
             })
    },

    SSOsite得到token以后将token存入浏览器端cookie和session中。

    public function checkToken(){
          $this->authUrl();
          session_start();
          if(isset($_POST['token'])){
              setcookie('usertoken',$_POST['token'],null);
              setcookie('userid',$_POST['userid'],null);
              $_SESSION['token'] = $_POST['token'];
              echo json_encode(array('auth'=>'SUC'));
          }
     }

    注意在浏览器通过ajax向SSOsite发送请求的情况下需要设置CORS(跨域资源共享)

    private function authUrl(){
            $origin = $_SERVER['HTTP_ORIGIN'];
            if (in_array($origin, $this->urlArr)) {
                header("Access-Control-Allow-Origin:" . $origin);
                header("Access-Control-Allow-Credentials: true ");
            }else{
                echo "error!";
                exit;
            }
        }

    设置完成以后,返回浏览器登录成功。

    第二部分

    下面我们用文字描述该过程

    ·浏览器请求onmpw的需要验证的页面。

    ·通过ajax带着cookie信息请求SSOsite系统。SSOsite系统在cookie中提取用户token。然后再次生成一个临时token存入session中,其键名为用户token。最后通知浏览器该用户已经登录成功,并且将临时token一并返回给浏览器。

    $tmptoken = Common::str_random();
    $_SESSION[$_SESSION['token']] = $tmptoken;

    ·浏览器接收到临时token,然后再次通过ajax将临时token发送给SSOsite进行验证。SSOsite验证完成临时token,将session中的临时token销毁。并且得到自己的sessionId返回给浏览器。

    public function authToken(){
        $this->authUrl();
        session_start();
        $tmptoken = $_POST['tmptoken'];
        if($tmptoken == $_SESSION[$_SESSION['token']]){
            unset($_SESSION[$_SESSION['token']]);
            echo json_encode(array('auth'=>'SUC','userid'=>$_COOKIE['userid'],'sessionId'=>session_id()));
        }else{
            echo json_encode(array('auth'=>'FAIL'));
        }
     }

    ·浏览器收到SSOsite返回的sessionId以后,将sessionId发送给onmpw。onmpw系统接收到浏览器带来的sessionId以后,用此sessionId来初始化自身的session。将先前存入浏览器cookie中的用户信息存入session中并且销毁cookie信息(当然在session开启之后,我们先检查session中是否存在用户信息,如果不存在则将cookie中的用户信息存入session,并销毁cookie)。

    $sessionId = $_POST['sessionId'];
    session_id($sessionId);
    session_start();
    if(!isset($_SESSION['userid'])){
        $userid = $_COOKIE['userid'];
        setcookie('userid',"",time()-3600,'/');
        $_SESSION['userid'] = $userid;
    }

    ·这样浏览器就可以知道用户信息存在,进行相应的操作。在第一部分步骤完成以后,用户也可以请求onmpw1。其步骤是和第二部分描述的相同。

    至此,通过php和ajax实现跨域单点登录的流程已经全部完成。其中有一部分核心代码,可以点此查看完整代码。希望本文对大家有所帮助。

  • 相关阅读:
    1007 Maximum Subsequence Sum(25 分)
    1006 Sign In and Sign Out(25 分)
    1005 Spell It Right
    1004 Counting Leaves
    Struts10分钟入门
    MyBais入门
    Hibernate注解
    save,flush,evict
    HQL连接查询
    Hibernate-延迟加载和立即加载
  • 原文地址:https://www.cnblogs.com/Shaw0/p/6292763.html
Copyright © 2020-2023  润新知