gpt4 book ai didi

php - session 验证破坏 session

转载 作者:搜寻专家 更新时间:2023-10-31 21:05:48 25 4
gpt4 key购买 nike

这是我的Session类:

class Session {

const SESSION_VALIDATOR = 'validSession';

/**
* Starts the session
*/
public static function init() {
session_start();

if (self::get(self::SESSION_VALIDATOR) !== true) {
session_unset();
session_destroy();
session_start();
self::set(self::SESSION_VALIDATOR, true);
}

session_regenerate_id(false);
}

/**
* Sets a value in the session
*
* @param string|int $key
* @param mixed $value
*/
public static function set($key, $value) {
$_SESSION[$key] = $value;
}

/**
* Gets a value from the session
*
* @param string|int $key
* @return mixed
*/
public static function get($key) {
if (isset($_SESSION[$key]))
return $_SESSION[$key];
else
return false;
}

/**
* Destroys the session
*/
public static function destroy() {
unset($_SESSION);
session_destroy();
}

}

在随机时间, session 中的 SESSION_VALIDATOR 变量似乎没有被设置,即使它没有改变,并且 session 随机销毁 - 即使用户已登录。是什么原因造成的这个?

更新 1:
这似乎只发生在我的本地主机环境 ( WAMPServer 2.5) 上,而不是在我的共享主机帐户上

更新 2:
它似乎没有发生,因为 Session::destroy() 方法在某个地方被意外调用,因为当我在方法内部抛出异常时,错误发生而没有抛出异常

更新 3:
忽略更新 #1 - 它也发生在我的共享主机帐户上

更新 4
试了andpei的回答,问题依旧。这是新的 Session 类:

class Session {

const SESSION_STARTED = true;
const SESSION_NOT_STARTED = false;
const SESSION_VALIDATOR = 'validSession';

private $sessionState = self::SESSION_NOT_STARTED;
private static $instance;

private function __construct() {

}

public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new self;
}

self::$instance->startSession();

return self::$instance;
}

public function startSession() {
if ($this->sessionState == self::SESSION_NOT_STARTED) {
$this->sessionState = session_start();
}

if (self::get(self::SESSION_VALIDATOR) !== true) {
$this->destroy();
session_start();
self::set(self::SESSION_VALIDATOR, true);
}

session_regenerate_id(false);

return $this->sessionState;
}

public function set($name, $value) {
$_SESSION[$name] = $value;
}

public function get($name) {
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
}
}

public function __isset($name) {
return isset($_SESSION[$name]);
}

public function __unset($name) {
unset($_SESSION[$name]);
}

public function destroy() {
if ($this->sessionState == self::SESSION_STARTED) {
$this->sessionState = !session_destroy();
unset($_SESSION);

return !$this->sessionState;
}

return false;
}
}

这让我觉得错误出在 SESSION_VALIDATOR 部分:

if (self::get(self::SESSION_VALIDATOR) !== true) {
$this->destroy();
session_start();
self::set(self::SESSION_VALIDATOR, true);
}

,所以我删除了它,现在错误不再发生。这个 session 验证真的有必要吗?为什么或者为什么不?如果保留它是明智的,那么如何解决错误?

最佳答案

这是一个设计问题,因为您无意中创建了 Session 对象的多个实例,然后所有实例都可能具有不同的 SESSION_VALIDATOR 值。

为避免此问题,您应该在 OOP 中使用 Singleton Pattern . = new Session 创建实例,getInstance() 方法将始终返回相同的实例对象。

你可以试试这个例子来创建一个 class Session with a Singleton .

评论更新

如果您不实例化Session 对象,那么它可能会被Garbage Collector 删除。 ,因为没有对它的引用。结果 SESSION_VALIDATOR 也被删除。在这种情况下,您会销毁 session (_unset,_destroy,_start),这会注销用户。

您可以尝试上面的示例,这将通过使用单例模式解决问题。

然后将整个对象存储为静态值。

更新关于SESSION_VALIDATOR的问题

这是一个设计问题,因为您在服务器端存储的状态取决于客户端的 session 状态,即垃圾收集器运行(服务器)或浏览器删除 cookie 或注销(客户端)。

理论上这意味着 HTTP 是无状态的,使用 session 来克服这个问题。实际上,这意味着您必须从 session 中读取一个值并确定登录是否有效。

因此,您的验证必须是一个函数而不是 SESSION_VALIDATOR 变量,它会根据 session 状态、它的值和您的用户数据库返回一个 bool 值,即与单例。

但是请不要在您的 session 中存储类似 login=true 的内容。使用您可以通过用户数据库验证的值。

另请参阅 OWASP PHP Security Cheat Sheet

类似问题:

关于php - session 验证破坏 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32553527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com