PHP $_SESSION 跨子域
PHP $_SESSION across subdomains
好的,所以我有 example.com
然后我使用 Javascript 运行 XHR 请求到 api.example.com
以前我有 api.example.com
作为 example.com/api
但我想将其移至子域并且登录工作正常,直到我将其移至 api.example.com
我正在测试登录脚本并尝试保持会话有效,但每次运行时都会清除 $_SESSION
db_connect.php
include_once("config.php");
ob_start();
session_start();
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
auth.php
<?php
require($_SERVER['DOCUMENT_ROOT'].'/db_connect.php');
if (!$db) {
die('Could not connect: ' . mysql_error());
}
$method = $_SERVER['REQUEST_METHOD'];
if ( isset($_GET['id']) ){
$id = $_GET['id'];
} else {
$id = 'all';
}
switch (strtoupper($method)) {
case "GET":
if ($_SESSION['auth']) {
$check = true;
} else {
$check = false;
}
$arr = json_encode(array('result'=>$check));
echo $arr;
break;
default:
echo "Streets closed pizza boy!";
}
signin.php
<?php
require($_SERVER['DOCUMENT_ROOT'].'/db_connect.php');
if (!$db) {
die('Could not connect: ' . mysql_error());
}
$method = $_SERVER['REQUEST_METHOD'];
if ( isset($_GET['id']) ){
$id = $_GET['id'];
} else {
$id = 'all';
}
switch (strtoupper($method)) {
case "POST":
$postdata = json_decode(file_get_contents("php://input"));
$src = (array)$postdata->user;
$password = hash( 'sha512', $src['password']);
$q = $db->query("SELECT *
FROM users u
WHERE u.email = '".$src['email']."'
AND u.password = '".$password."'");
if($q->num_rows > 0){
$check = true;
$_SESSION['auth'] = 1;
$maps = array();
while($row = mysqli_fetch_array($q)) {
$product = array(
'auth' => 1,
'id' => $row['id'],
'name' => $row['name'],
'email' => $row['email'],
'access' => $row['access']
);
array_push($maps, $product);
}
//$_SESSION['company_id'] = $product['company_id'];
}else{
$check = false;
}
$_SESSION['id'] = $product['id'];
$_SESSION['email'] = $product['email'];
setcookie("username", $productx§['email'], time()+(84600*30));
$arr = json_encode(array('result'=>$check, 'user'=>$maps));
echo $arr;
break;
default:
echo "Your favorite color is neither red, blue, or green!";
}
我试过将db_connect.php设置为
<?php
include_once("config.php");
ob_start();
session_set_cookie_params(0, '/', '.example.com');
session_start();
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
但这没有任何作用,会话变量也丢失了。
PHP 文件也通过 AJAX 调用。
是否所有页面是否 angularjs DOM 都应该连接到数据库?
尝试设置会话名称:
$session_name = session_name("my_session");
然后,将会话 cookie 设置为跨越所有子域:
session_set_cookie_params(0, "/", ".example.com");
然后执行 session_start()
- 它现在应该可以工作了。
要使用跨子域会话,您必须在所有子域项目中使用以下代码:
session_name('SessionName');
session_set_cookie_params(
1800,
ini_get('session.cookie_path'),
'.example.com'
);
session_start();
重要:仅当所有子域都在一台服务器上时它才有效(因为会话存储在一个 tmp 目录中)。如果你想在不同的服务器上使用类似的会话,使用SAN存储或者将会话存储在memcached等
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://122.122.122.122:11211');
session_name('SessionName');
session_set_cookie_params(
1800,
ini_get('session.cookie_path'),
'.exmaple.com'
);
session_start();
.htaccess 在 api.example.com
# CORS Headers (add this)
<ifModule mod_headers.c>
Header add Access-Control-Allow-Origin "http://example.com"
## Post the domain that will be doing the XHR requests
Header add Access-Control-Allow-Credentials: "true"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
</ifModule>
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
example.com
Post您主网站header中的以下内容
ini_set('session.cookie_domain', '.example.com' );
session_start();
XHR 请求
现在我们需要 post 从 example.com 到 api.example.com 我' m 使用 AngularJS 和这个
$http({
method: 'GET',
url: '//api.example.com/auth/',
xhrFields: {
withCredentials: true
},
crossDomain: true
}).success....
同时更改您的配置以允许使用凭据发送
.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
//rest of route code
这对我有用:
ini_set('session.cookie_domain', substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
session_start();
起初,它不起作用,我不得不删除所有 cookie,最后它按预期工作了。
好的,所以我有 example.com
然后我使用 Javascript 运行 XHR 请求到 api.example.com
以前我有 api.example.com
作为 example.com/api
但我想将其移至子域并且登录工作正常,直到我将其移至 api.example.com
我正在测试登录脚本并尝试保持会话有效,但每次运行时都会清除 $_SESSION
db_connect.php
include_once("config.php");
ob_start();
session_start();
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
auth.php
<?php
require($_SERVER['DOCUMENT_ROOT'].'/db_connect.php');
if (!$db) {
die('Could not connect: ' . mysql_error());
}
$method = $_SERVER['REQUEST_METHOD'];
if ( isset($_GET['id']) ){
$id = $_GET['id'];
} else {
$id = 'all';
}
switch (strtoupper($method)) {
case "GET":
if ($_SESSION['auth']) {
$check = true;
} else {
$check = false;
}
$arr = json_encode(array('result'=>$check));
echo $arr;
break;
default:
echo "Streets closed pizza boy!";
}
signin.php
<?php
require($_SERVER['DOCUMENT_ROOT'].'/db_connect.php');
if (!$db) {
die('Could not connect: ' . mysql_error());
}
$method = $_SERVER['REQUEST_METHOD'];
if ( isset($_GET['id']) ){
$id = $_GET['id'];
} else {
$id = 'all';
}
switch (strtoupper($method)) {
case "POST":
$postdata = json_decode(file_get_contents("php://input"));
$src = (array)$postdata->user;
$password = hash( 'sha512', $src['password']);
$q = $db->query("SELECT *
FROM users u
WHERE u.email = '".$src['email']."'
AND u.password = '".$password."'");
if($q->num_rows > 0){
$check = true;
$_SESSION['auth'] = 1;
$maps = array();
while($row = mysqli_fetch_array($q)) {
$product = array(
'auth' => 1,
'id' => $row['id'],
'name' => $row['name'],
'email' => $row['email'],
'access' => $row['access']
);
array_push($maps, $product);
}
//$_SESSION['company_id'] = $product['company_id'];
}else{
$check = false;
}
$_SESSION['id'] = $product['id'];
$_SESSION['email'] = $product['email'];
setcookie("username", $productx§['email'], time()+(84600*30));
$arr = json_encode(array('result'=>$check, 'user'=>$maps));
echo $arr;
break;
default:
echo "Your favorite color is neither red, blue, or green!";
}
我试过将db_connect.php设置为
<?php
include_once("config.php");
ob_start();
session_set_cookie_params(0, '/', '.example.com');
session_start();
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
但这没有任何作用,会话变量也丢失了。
PHP 文件也通过 AJAX 调用。
是否所有页面是否 angularjs DOM 都应该连接到数据库?
尝试设置会话名称:
$session_name = session_name("my_session");
然后,将会话 cookie 设置为跨越所有子域:
session_set_cookie_params(0, "/", ".example.com");
然后执行 session_start()
- 它现在应该可以工作了。
要使用跨子域会话,您必须在所有子域项目中使用以下代码:
session_name('SessionName');
session_set_cookie_params(
1800,
ini_get('session.cookie_path'),
'.example.com'
);
session_start();
重要:仅当所有子域都在一台服务器上时它才有效(因为会话存储在一个 tmp 目录中)。如果你想在不同的服务器上使用类似的会话,使用SAN存储或者将会话存储在memcached等
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://122.122.122.122:11211');
session_name('SessionName');
session_set_cookie_params(
1800,
ini_get('session.cookie_path'),
'.exmaple.com'
);
session_start();
.htaccess 在 api.example.com
# CORS Headers (add this)
<ifModule mod_headers.c>
Header add Access-Control-Allow-Origin "http://example.com"
## Post the domain that will be doing the XHR requests
Header add Access-Control-Allow-Credentials: "true"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
</ifModule>
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
example.com
Post您主网站header中的以下内容
ini_set('session.cookie_domain', '.example.com' );
session_start();
XHR 请求
现在我们需要 post 从 example.com 到 api.example.com 我' m 使用 AngularJS 和这个
$http({
method: 'GET',
url: '//api.example.com/auth/',
xhrFields: {
withCredentials: true
},
crossDomain: true
}).success....
同时更改您的配置以允许使用凭据发送
.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
//rest of route code
这对我有用:
ini_set('session.cookie_domain', substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
session_start();
起初,它不起作用,我不得不删除所有 cookie,最后它按预期工作了。