服务器如何知道会话何时终止?
Session 基本上是一堆数据,存储在服务器上。客户端通过会话 ID 识别并匹配到特定会话,存储在会话和客户端的 cookie 中,默认名称为 PHPSESSID。 (你可以在浏览器中找到它的值,或者在PHP中使用session_id()函数。)如果浏览器删除了这个cookie,客户端的会话ID就丢失了,客户端无法取回存储在其中的其他数据服务器上的会话。这些数据最终会被垃圾收集器删除。
每次调用session_start() 时都会以一定的概率调用垃圾收集器。概率等于gc_probability/gc_divisor。如果会话存在超过gc_maxlifetime 秒,垃圾收集器将删除会话数据。您可以在phpinfo() 输出中检查所有这些值,或者使用例如ini_get('session.gc_maxlifetime')。那是关于服务器上的会话数据。现在关于客户端。
会话配置包含一个值session.cookie_lifetime。引用PHP manual:
session.cookie_lifetime 以秒为单位指定发送到浏览器的 cookie 的生命周期。值 0 表示“直到浏览器关闭”。默认为 0。
来自PHP Sessions and security:
0 有特殊含义。它告诉浏览器不要将 cookie 存储到永久存储中。因此,当浏览器终止时,会话 ID cookie 会立即被删除。如果开发者设置的不是 0,它可能允许其他用户使用会话 ID。大多数应用程序应该为此使用“0”。如果需要自动登录功能,请实现您自己的安全自动登录功能。不要使用会话 ID。
您可以使用以下任何方式检查设置:
-
phpinfo(),在session 部分中查找session.cookie_lifetime。
session_get_cookie_params()['lifetime']
ini_get('session.cookie_lifetime')
所以基本上,如果会话 cookie 生存期为 0,浏览器会在关闭时将其删除,客户端将无法访问会话数据。
如果有人要访问该会话 ID,他们可以访问所有相同的信息吗?
是的。只要(任何)客户端都知道该 ID,并且会话数据在服务器上没有被删除,客户端就可以访问它。
除了简单地检查会话信息之外,是否还需要额外的安全级别来识别用户?
这取决于您的应用程序。获取会话 ID 并非易事,需要拦截通信或直接访问客户端数据。使用基于TLS 的加密连接可以防止拦截。获取客户端数据需要一些恶意软件。
This article 描述了一种用于用户身份验证的更安全的 cookie 实现。简而言之,虽然它仍然不能阻止cookie hijacking,但它为您提供了一种检测它、通知用户并防止被盗 cookie 被重新使用的方法。
Another article 列表更全面地概述了用户身份验证的良好做法。像往常一样,安全性要求整个项目以安全的方式实施,而不仅仅是其中一个看似关键的部分。但如果我的建议,不要过度。对于每个项目的特定要求,工作量应该是合理的。