我有一个登录和注销正常工作的应用程序。一旦用户注销,并尝试访问他需要身份验证的页面,他就会被重定向到登录屏幕。
我的问题所在。如果我在登录时,如果我复制cookie值并将其保存在文件中。注销后,我改变了cookie并添加了相同的值,我以相同的用户身份重新登录到应用程序。
在注销时,我编写了一个循环遍历所有cookie并删除它们的函数。
我的理解是cookie既在客户端也在服务器端。因此,如果cookie被删除,它们将被双方删除,并且服务器在被清除后将无法识别它们,即使浏览器再次将它们发回(显然情况并非如此)。
我这样做的原因是因为这是我们的安全审核员提出的要点之一,我需要找到解决这个漏洞的方法。 (此时执行https是不可行的)
如果有人能指出我如何清除服务器端的cookie,我会很高兴,所以,当下次有人用相同的cookie命中服务器时,它不接受它一个有效的cookie。
修改
我使用codeigniter会话和tank_auth作为身份验证库。在注销时,库本身调用
$this->ci->session->sess_destroy();
更加确定,我在几次尝试后尝试了以下内容:
session_start();
session_unset();
session_destroy();
session_write_close();
setcookie(session_name(),'',0,'/');
session_regenerate_id(true);
我的常规注销工作正常,如果我尝试直接访问该页面,则无法打开。
但是如果我在登录时,我拿走了我的cookie,将其保存在某个地方 - 成功注销并将cookie替换为旧版本,我会立即回到会话中。 / p>
有没有办法阻止这种行为 - 服务器端在销毁之后不会接受会话。我还确保我的服务器和php在同一时区(用date_default_timezone_set
设置)。
答案 0 :(得分:2)
Cookie根本不存储在服务器上。这些存储在浏览器中,然后在请求标头中发送到服务器。您可以轻松找到允许您创建/编辑/删除cookie的浏览器的软件和插件。因此,您不应将敏感信息存储在cookie中。基本上您要做的是将用户数据存储在会话中,然后将会话名称存储在cookie中。通常,当您使用函数session_start()时,这将在php中自动完成。
如果您使用Codeigniter,则php会话功能将包装在每个页面加载时自动加载的CI会话库中。因此,您不想在$ _COOKIE中存储数据,而是希望通过会话库中的userdata方法获取/设置数据:
//in your controller
//save session data
$userdata = array(
"isLoggedIn"=>true,
"username"=>$_POST['username']
);
$this->session->set_userdata($userdata);
//get session data later
$isLoggedIn = $this->session->userdata("isLoggedIn");
if(!$isLoggedIn){
//if the user is not logged in, destroy the session and send to the login screen
$this->session->sess_destroy();
redirect("/");
}
请注意,上面的代码未经过测试,只能让您知道去哪里。如果会话方法不适合您,您可能需要手动加载库:
//in the __construct method of your controller:
$this->load->library("session");
您可以在此处找到更多信息: http://ellislab.com/codeigniter/user-guide/libraries/sessions.html 和这里: http://www.php.net/manual/en/book.session.php
答案 1 :(得分:0)
谢谢你的答案。
这是我后来想到的。我不确定是什么导致了这一点,但会议在尝试所有内容后没有失效。我将codeigniter上的会话移到了数据库。然后注销开始正常工作,在注销后,如果“被盗”/“已保存”的cookie再次放入浏览器中,则不会将用户重新登录。
那就是解决它的原因。