两个有用的链接:
http://blog.teamtreehouse.com/how-to-create-bulletproof-sessions
https://paragonie.com/blog/2015/04/fast-track-safe-and-secure-php-sessions
我设法做到了,但现在每次有人尝试从两台设备登录时,具有“旧”会话的设备无效,因为 user_hash 从新设备更改并注销用户旧会话。
虽然这可能取决于您的安全要求,但我在上面发布的first link 表示:
将旧会话标记为已过时,并将其标记为在 10 秒 [或适合您需要的某个时间] 后过期。这样,任何排队的请求仍然可以访问过期的会话,但我们不必让它永远打开。
static function regenerateSession()
{
// If this session is obsolete it means there already is a new id
if(isset($_SESSION['OBSOLETE']) || $_SESSION['OBSOLETE'] == true)
return;
// Set current session to expire in 10,30,100 seconds etc.
$_SESSION['OBSOLETE'] = true;
$_SESSION['EXPIRES'] = time() + 10; //or 30 seconds or whatever.
// Create new session without destroying the old one
session_regenerate_id(false);
// Grab current session ID and close both sessions to allow other scripts to use them
$newSession = session_id();
session_write_close();
// Set session ID to the new one, and start it back up again
session_id($newSession);
session_start();
// Now we unset the obsolete and expiration values for the session we want to keep
unset($_SESSION['OBSOLETE']);
unset($_SESSION['EXPIRES']);
}
所以我实现了一个系统,每次用户登录和/或导航到 Web 应用程序中的其他页面时,我都会生成一个新的哈希值,将其存储在数据库中,然后将其存储在全局$_SESSION['id'] 变量。
就个人而言,我怀疑它的效率极低,并且会导致您在这种不断的改造中产生大量的服务器负载开销。只是不需要。
如果您真的想重新设计会话,只需使用session_regenerate_id() 并将其设置为一个时间值(例如每 10 分钟一次),如本文顶部的outlined in the first link。
唯一重要的是会话标识会话数组中的所有值浏览器或最终用户永远不会看到。
所以;只要您的会话 id 是 LONG 随机值,它就会隐藏在明显的视线中。从second link above 获取更多关于如何确保 PHP 为您提供更多随机和更长命名会话 id 的详细信息。
php.ini:
session.save_handler = files
session.use_cookies = 1
session.cookie_secure = 1
session.use_only_cookies = 1
session.cookie_domain = "example.com"
session.cookie_httponly = 1
session.entropy_length = 32
session.entropy_file = /dev/urandom
session.hash_function = sha256
session.hash_bits_per_character = 5
如果将会话存储在数据库中,请确保为会话 ID 设置足够长的列名,否则会话将由于会话名称被截断而永远无法连接。
其他一些因素:
请确保 PHP 将您的会话 cookie 设置为 encrypted。无论您的 TLS 连接的状态如何,这都必须手动完成。参见上面的session.cookie_secure=1。
1234563比较浏览器类型/客户端 IP 仍然与会话记录中的内容进行比较。这两种方法中的每一种都可能存在问题,例如移动连接上的少数人可能会在登录期间更改 IP,或者多个设备上的用户可能会在每个设备上使用不同的浏览器,但可以根据需要找到一种方法进行比较 (这在页面顶部的first link 中也有引用)。
如上所述,$_SESSION 数据永远不会存储在客户端计算机上,因此从数据库中散列值以存储在 $_SESSION 中很可能超出了您的安全需求。
(唯一的)最重要的一点是会话 ID 是安全的并且足够大,可以轻松容纳潜在的黑客使用虚假会话 ID 钓鱼,就像在我的世界中玩战舰一样