几天来,我一直在寻找一个安全的认证和会话管理机制,以供我的单页应用程序使用。根据有关单页应用程序和身份验证的众多教程和博客文章,将JWT存储在localStorage或普通cookie中似乎是最常见的方法,但将JWT用于会话不是一个好主意,因此这不是该应用程序的选择。
要求
然而,浏览器没有保存cookie(当我检查Chrome的本地cookie时它不在那里)。因此,当以下代码运行时:
这个请求头中没有cookie信息,因此服务器拒绝了该请求。
需要特别处理才能确保浏览器在接收到登录响应后保存cookie吗?我阅读的各种资料都说,浏览器只有在用户被重定向时才保存响应cookie,但是由于这是一个SPA,我不想进行任何“硬”重定向。
涉及的SPA是用Vue.js编写的,但我认为它适用于所有SPAs。我想知道人们如何处理这种情况。
此主题上我阅读的其他内容:
- 认证和会话管理的SPA最佳实践 - 使用withCredentials=True提交HTTPOnly Cookie的XmlHTTPRequest是否有效? - 停止使用JWT会话,第二部分:为什么你的解决方案不起作用
- 登录应该是可撤销的。例如,如果检测到用户帐户上的可疑活动,应该立即撤销该用户的访问权限并要求重新登录。同样,像密码重置这样的事情应该撤销所有现有的登录。
- 身份验证应该通过Ajax进行。之后不应该发生任何浏览器重定向(“硬”重定向)。所有导航都应该在SPA内部完成。
- 一切都应该跨域工作。SPA将位于www.domain1.com,服务器将位于www.domain2.com。
- JavaScript不应该访问服务器发送的敏感数据,如会话ID。这是为了防止XSS攻击,其中恶意脚本可以从常规cookie、localStorage或sessionStorage中窃取令牌或会话ID。
HttpOnly
cookie。流程如下:
- 用户到达登录页面并提交用户名和密码。
- 服务器对用户进行身份验证并将会话ID作为
HttpOnly
响应cookie发送。 - 然后,SPA在随后向服务器发出的XHR请求中包括此cookie。这似乎可以使用
withCredentials
选项实现。 - 当请求被发送到受保护的端点时,服务器查找cookie。如果找到了,它会交叉检查该会话ID与数据库表以确保会话仍然有效。
- 当用户注销时,会话从数据库中删除。下次用户访问站点时,SPA会收到401/403响应(因为会话已过期),然后将用户带到登录屏幕。
HttpOnly
标志,JavaScript将无法读取其内容,因此只要通过HTTPS传输,它就会安全免受攻击。
挑战
这是我遇到的具体问题。我的服务器已配置为处理CORS请求。在用户进行身份验证后,它会在响应中正确地发送cookie:HTTP/1.1 200 OK
server: Cowboy
date: Wed, 15 Mar 2017 22:35:46 GMT
content-length: 59
set-cookie: _myapp_key=SFMyNTYBbQAAABBn; path=/; HttpOnly
content-type: application/json; charset=utf-8
cache-control: max-age=0, private, must-revalidate
x-request-id: qi2q2rtt7mpi9u9c703tp7idmfg4qs6o
access-control-allow-origin: http://localhost:8080
access-control-expose-headers:
access-control-allow-credentials: true
vary: Origin
然而,浏览器没有保存cookie(当我检查Chrome的本地cookie时它不在那里)。因此,当以下代码运行时:
context.axios.post(LOGIN_URL, creds).then(response => {
context.$router.push("/api/account")
}
并且账户页面已被创建:
created() {
this.axios.get(SERVER_URL + "/api/account/", {withCredentials: true}).then(response => {
//do stuff
}
}
这个请求头中没有cookie信息,因此服务器拒绝了该请求。
GET /api/account/ HTTP/1.1
Host: localhost:4000
Connection: keep-alive
Accept: application/json
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,tr;q=0.6
需要特别处理才能确保浏览器在接收到登录响应后保存cookie吗?我阅读的各种资料都说,浏览器只有在用户被重定向时才保存响应cookie,但是由于这是一个SPA,我不想进行任何“硬”重定向。
涉及的SPA是用Vue.js编写的,但我认为它适用于所有SPAs。我想知道人们如何处理这种情况。
此主题上我阅读的其他内容:
- 认证和会话管理的SPA最佳实践 - 使用withCredentials=True提交HTTPOnly Cookie的XmlHTTPRequest是否有效? - 停止使用JWT会话,第二部分:为什么你的解决方案不起作用