- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这是我的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/
我正在尝试完成撤消/重做。我正在使用loadFromJSON(...)从我存储在数组中的 Canvas 状态重新构建 Canvas 。基本上,我的想法是破坏现有的 Canvas 并重新构建 Canva
在某些情况下,我有一个在 iframe 中打开的网页。当它被加载到那个 iframe 中时,我需要它将窗口位置设置为资源以下载文件(所有这些都是为了更新 GreaseMonkey 脚本......所有
当我创建 Intent 时: Intent in = new Intent(this, myclass.class); this.startActivity(in); 我创建了一个新的 Intent
我正在我本地版本的 Wordpress 网站上为 Wordpress 创建新的短代码。 在 functions.php 中,我添加了例如: function shortTest() { re
我正在为机械网站制作 JavaScript 闪卡游戏。因为我想将方程写在卡片上,所以我需要使用 delta(Δ) 符号。 一张卡片可能有:一侧是“功率方程”,另一侧是“P=W/Δt”。如果卡片从第一面
我编写了以下代码: document.addEventListener("DOMContentLoaded", ()=>{ let menu = document.querySelector(
我的浏览器同步工作正常,但我仍然很难处理之前的 html 的缓存。即使选中了 Chrome 的“禁用缓存”,甚至在隐身模式下也是如此! 要加载页面更改,我总是必须“清除缓存并硬重新加载”。 我想知道,
我注意到每次打开和关闭(通过单击菜单项或单击菜单外的某个区域)时,上下文菜单 ( Ext.menu.Menu ) s 不会从 DOM 中删除,它们只是以某种方式变得不可见。 如何改变这个? 最佳答案
给定依赖记录类型: Record FinPath : Type := mkPath { fp_head : S i; fp_tail
在 Husdon/Jenkins 中,我可以在构建被破坏时设置通知,以向进行破坏构建的 checkin 的用户发送电子邮件。如何在 Teamcity 中执行此操作? 我知道个人用户可以通过 Teamc
我注意到每次打开和关闭(通过单击菜单项或单击菜单外的某个区域)时,上下文菜单 ( Ext.menu.Menu ) s 不会从 DOM 中删除,它们只是以某种方式变得不可见。 如何改变这个? 最佳答案
使用 MIMEMultipart('alternative') 发送 html 和 pain-text 时 将 html 转换为文本时,html 的 anchor 换行 http://127.0.0.
每当我的应用程序最小化时,我都会启动一个服务,该服务向我的 HTTP 服务器发送拉取请求以检查通知,当应用程序恢复时,服务将被终止(以及计划的可运行项)。一切正常,直到我决定终止该应用程序(将其从正在
我意识到该框架处于 alpha 阶段,但正在实现 jQuery Mobile破坏了我的omniauth 身份验证。当我尝试登录时,一旦我尝试点击/auth/twitter Controller ,jQ
我对 Angular 比较陌生,经过几个小时的调试,我发现添加 jquery 时存在一些不兼容性。该指令在没有 jquery 的情况下工作正常,但在使用 jquery 时会中断:/ 这是一个 plnk
我发现,因为我正在处理的所有表单都有一个包含“name =“submit””属性的提交按钮,所以当我单击应该触发表单提交的链接时,触发器提交会中断. 有谁知道我该如何解决这个问题。 下面的 JQuer
我遇到了一个问题:/我得到了一个 CSS 东西,它使悬停时背景位置发生变化。但是当我在 javascript 中运行一个改变悬停的函数后,CSS 停止工作。 这是函数: function tree()
谁能给出一个完整的例子来说明 qooxdoo 1.6 中的 dispose 和 destruct 是如何工作的? ,我在 qooxdoo 演示或文档中找不到任何好的示例。 谢谢你的建议。 最佳答案 处
我对 JFormattedTextField 有疑问(我将它用作我们所有文本字段的基类)。 今天我尝试向该字段的文档添加一个文档过滤器,它工作得很好,但前提是它没有设置格式化程序工厂。 问题是,当设置
我有一个点击事件 $('#ship_Move').click(function (event) { event.stopPropagation();
我是一名优秀的程序员,十分优秀!