PHP跨域Cookie的处理

Tuesday, November 27, 2018

概述

跨域 Cookie 指的是用户在 A 站设置 Cookie 后,在 B 站希望使用 A 站的 Cookie,这个时候的一种解决办法是在 B 站使用 ajax 请求异步去 A 站接口获取,由于是在 B 站异步请求 A 站接口,所以是跨域Cookie。

以上是使用场景,下面说下具体的操作方法。

A站

跨域 Cookie 首先要解决的是跨域的问题,可以通过在 A 站设置 header 头来允许跨域,不过,常规的跨域设置是无法传递 Cookie 的,此时需要设置 Access-Control-Allow-Credentials 为 true,这里要注意设置允许传递 Cookie 后必须明确限定跨域允许域名

  1. 在 A 站先设置 Cookie (site_a_cookie_write.php)
<?php
    $token = 'www.a.com-'.time();
    $result = setcookie('token', $token, time()+86400, '/', 'www.a.com');
    echo $token;
?>
  1. 提供读取 A 站 Cookie 接口 (site_a_cookie_read.php)

注意这里明确指明了允许跨域的域名是 http://www.b.com,如果设置允许 Cookie 传递后不明确指明允许域名,ajax 异步调取接口的时候就会报错,提示需要明确指明异步请求方的域名。

<?php
    header("Access-Control-Allow-Origin:http://www.b.com");
    header("Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE");
    header("Access-Control-Allow-Headers:x-requested-with,content-type");
    header("Access-Control-Expose-Headers:Authorization, authenticated");
    header("Access-Control-Allow-Credentials:true");
    echo json_encode([
    	'token' => $_COOKIE['token'] ?? null
    ]);
?>

B站

为了使跨域时 ajax 可以传递过来 Cookie 信息,ajax 需要单独设置两个参数:xhrFields.withCredentials 和 crossDomain,两个都要设置为 true。

  1. B 站检测 Cookie 代码 (site_b_cookie_test.php)
<?php
    print_r($_COOKIE);
?>
  1. B 站异步读取 A 站 Cookie (site_b_cookie_get.php)
<!DOCTYPE html>
<html>
<head>
	<title>B站异步读取A站Cookie</title>
</head>
<body>
    <script src="https://cdn.bootcss.com/jquery/1.11.1/jquery.js"></script>
    <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
    <script type="text/javascript">
    	$.ajax({
    	    url: "http://www.a.com/site_a_cookie_read.php",
    	    type:"get",
    	    data:"",
    	    dataType:"json",
    	    xhrFields: {
    	        withCredentials: true
    	    },
    	    crossDomain: true,
    	    success: function(data){
    	    	let token = data.token;
    	    	if(token){
    	    		$.cookie('token', token);
    	    	}
    	    }
    	})
    </script>
</body>
</html>

测试

经过上述步骤,就可以在 B 站通过 ajax 跨域获取用户在 A 站的 Cookie 了,以下是测试流程:

测试前最好先检查下两个域名下是否有 Cookie,如果有的话先清掉 Cookie 后再开始测试。

  1. 访问 http://www.b.com/site_b_cookie_test.php,可以看到 B 站此时是没有 Cookie 设置的。

  2. 访问 http://www.a.com/site_a_cookie_write.php 为浏览器写入 A 站的Cookie。

  3. 访问 http://www.b.com/site_b_cookie_get.php 异步从 A 站读取 上一步 写入的 Cookie 信息,获取成功并且有值后写入 B 站的 Cookie 中。

  4. 访问 http://www.b.com/site_b_cookie_test.php,可以看到 B 站此时已经有 Cookie 了,且和 A 站设置的值一致。

PHP PHP

基于docker实现mysql主从Yii2-Queue实现轻量级消息队列