【发布时间】:2016-05-01 19:07:52
【问题描述】:
我正在从受会话保护的页面执行标准 getJSON 查询:
$.getJSON('queries.php',{q: 'updateEvent', param1: p1},
function(data){
...
}
);
在我的会话构造函数中,我设置了以下内容:
function startSession()
{
ini_set('session.use_only_cookies', SESSION_USE_ONLY_COOKIES);
$cookieParams = session_get_cookie_params();
session_set_cookie_params(
$cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
SESSION_SECURE,
SESSION_HTTP_ONLY
);
session_start();
if ( SESSION_REGENERATE_ID )
session_regenerate_id(SESSION_REGENERATE_ID);
}
如果我将SESSION_REGENERATE_ID 设置为true,那么我的getJSON 会发送一个令牌,但会收到一个不同的令牌,从而导致请求失败。所以目前我正在处理 SESSION_REGENERATE_ID 设置为 false。
有没有办法让 getJSON 在这种情况下工作?
编辑:所有文件都在同一个域下。
我们有 index.php,其中包含 js,我们有 queries.php,它是由 ajax 请求调用的 php 文件,我们有 s_session.php,其中包含上面编写的构造函数。
文件 index.html 和 queries.php 在开始时都以这种方式受到保护:
include "s_session.php";
if(!$login->isLoggedIn()) {
header('Content-Type: application/json');
echo json_encode(array('content' => 'Login failed'));
exit;
}
PHPSESSID 位于 set-cookie 下的 ajax 请求的标头中。 答案中返回的 PHPSESSID 与 session_regenerate_id 的预期不同。
如果 SESSION_REGENERATE_ID 设置为 FALSE,则请求将毫无问题地通过。如果设置为 TRUE,则会收到错误消息“登录失败”。
这里是 isLoggedIn() :
public function isLoggedIn() {
//if $_SESSION['user_id'] is not set return false
if(ASSession::get("user_id") == null)
return false;
//if enabled, check fingerprint
if(LOGIN_FINGERPRINT == true) {
$loginString = $this->_generateLoginString();
$currentString = ASSession::get("login_fingerprint");
if($currentString != null && $currentString == $loginString)
return true;
else {
//destroy session, it is probably stolen by someone
$this->logout();
return false;
}
}
$user = new ASUser(ASSession::get("user_id"));
return $user->getInfo() !== null;
}
编辑 2:这是完整的 ASSession 代码:
class ASSession {
/**
* Start session.
*/
public static function startSession()
{
ini_set('session.use_only_cookies', SESSION_USE_ONLY_COOKIES);
session_start();
$s = $_SESSION;
$cookieParams = session_get_cookie_params();
session_set_cookie_params(
$cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
SESSION_SECURE,
SESSION_HTTP_ONLY
);
if ( SESSION_REGENERATE_ID )
session_regenerate_id(SESSION_REGENERATE_ID);
//$_SESSION = $s;
}
/**
* Destroy session.
*/
public static function destroySession() {
$_SESSION = array();
$params = session_get_cookie_params();
setcookie( session_name(),
'',
time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]
);
session_destroy();
}
/**
* Set session data.
* @param mixed $key Key that will be used to store value.
* @param mixed $value Value that will be stored.
*/
public static function set($key, $value) {
$_SESSION[$key] = $value;
}
/**
* Unset session data with provided key.
* @param $key
*/
public static function destroy($key) {
if ( isset($_SESSION[$key]) )
unset($_SESSION[$key]);
}
/**
* Get data from $_SESSION variable.
* @param mixed $key Key used to get data from session.
* @param mixed $default This will be returned if there is no record inside
* session for given key.
* @return mixed Session value for given key.
*/
public static function get($key, $default = null) {
if(isset($_SESSION[$key]))
return $_SESSION[$key];
else
return $default;
}
}
编辑 3:这里是请求标头和响应 cookie:
我注意到在onload 期间执行的第一个getJSON 是成功的。在用户之后完成并由用户触发的所有其他操作均未成功
【问题讨论】:
-
我理解您在我的回答中的评论(我现在删除它,如果我能为您找到任何其他解决方案,将取消删除)。那么,您的代币实际上是如何工作的呢?如果会话数据存在,那么它只会改变 session_id,所有其他的应该保持不变。为什么它发送错误的令牌?它只是将 session_id 作为令牌发送吗?
-
是的,只结束 session_id。我读过 getJSON 默认情况下不发送凭据。这就是为什么 ajax 有一个名为 withCredentials 的 xhrField 应该设置为 true。但我不知道如何将它包含在 getJSON 中,因为官方文档中没有专门包含 xhrFields 的语法
-
更具体地说,php 页面返回一条错误消息,指出无法登录(因此无法识别会话数据)。在控制台中,我看到请求标头 set-cookie 正在发送一个 PHPSESSID,但错误消息附带的响应 PHPSESSID 不同
-
如果这样可以解决您的问题,只需使用
$.ajax函数并使用额外参数dataType:"json"使其像$.getJSON一样工作。像这样$.ajax({url:url,xhrFields: {withCredentials: true }, dataType:"json"});告诉我,如果这对你有用。 -
这只是一个
$.getJSON()呼叫还是多个?而究竟是什么时候这些调用被执行了?在页面加载期间或之后?如果有多个调用,它们是否同时执行并且它们全部都失败了?请发布相关的请求和响应标头。
标签: php jquery session getjson