在学习会话管理之前,我们首先需要巩固下 HTTP 协议的知识。
HTTP 协议是无状态无连接的协议,服务端对于客户端每次发送的请求都认为它是一个新的请求,上一次会话和下一次会话是没有联系的。因为它无法保存登录状态,所以从协议本身来说,它不适合用来做会话管理。
因此,我们会使用一个上层应用去实现我们的会话管理功能。这个应用可以在切换页面时保持登录状态,并且对用户是透明的,这样就使得我们能在短时间内再次访问一个登录过的页面,就会保持登录状态。
经过上述内容的学习,你已经知道了会话管理具有什么作用。接下来,让我们具体学习下会话管理的两种典型方式,即基于 session 的认证以及基于 Token 的认证。
基于 session 的认证
Web 应用可以基于 session 的认证来实现保持登录,它的具体实现方式如下图所示:
用户在首次访问 Web 应用时,会将自己的账号密码通过 POST 方式进行上传,然后 Web 应用服务器会对账号密码进行检查。如果检查通过就会给用户配置一个 sessionid,并将它存储在服务器内存中,之后再把这个 sessionid 发送给用户。
注意这里 sessionid 的位置可能在 URL、隐藏域以及 cookie 中。由于 cookie 信息较为隐蔽些,所以将 sessionid 放在 cookie 中相对来说更为安全,因此这一实现方式也最普遍。
用户在收到 Web 应用服务器的回应之后,再次对 Web 应用发起请求的 cookie 中就会自动包含 sessionid 信息。Web 应用服务器会对其中的 sessionid 信息进行检查,以获取用户的登录信息,如果信息正确,就让用户处于登录成功的状态,否则需要重新进行登录过程的认证。
值得一提的是,为了安全考虑,Web 应用通常会给 sessionid 设置一个过期时间,使得 sessionid 仅在某个时间段内有效,这样就可以有效地抵御攻击者盗用 sessionid 绕过身份认证的行为。
到这里,我们已经学习了 Web 应用是如何利用 session 进行身份认证的。而这里还有一个很重要的知识点我们有必要深入了解一下,那就是在 session 进行身份认证中存在的典型攻击方式——会话固定攻击。
在之前的学习中,我们知道了 sessionid 可以存在于 URL 中。在这种情况下,如果登录前后 sessionid 不变化,那么攻击者就可以发起会话固定攻击。