我正在创建单页应用程序。我已经创建了登录注销操作,它们工作正常。但是,如果用户注销并且不会在浏览器中刷新页面,则由于“CSRF不匹配”错误,他无法再次登录。
步骤:
1。在第一页加载时,csrf是本地视图:
<div class="app" id="app" data-csrf="<%= _csrf %>"></div>
2。用户使用此令牌成功登录:
420["post",{"method":"post","headers":{},"data":{"_csrf":"VHcT2F44-KhZMJmhcAVB1H69BgTMWMZji9_8","login":"alex","password":"123"},"url":"http://127.0.0.1:1337/login"}]
430[{"body":{"id":"560e5756cd01633407eea8be"},"headers":{cut headers},"statusCode":200}]
3。然后,用户使用此令牌注销:
421["post",{"method":"post","headers":{},"data":{"_csrf":"VHcT2F44-KhZMJmhcAVB1H69BgTMWMZji9_8"},"url":"http://127.0.0.1:1337/logout"}]
431[{"body":"ok","headers":{cut headers},"statusCode":200}]
4。如果他再次尝试登录,他将发现“CSRF不匹配”错误,我预计会:
422["post",{"method":"post","headers":{},"data":{"_csrf":"VHcT2F44-KhZMJmhcAVB1H69BgTMWMZji9_8","login":"alex","password":"123"},"url":"http://127.0.0.1:1337/login"}]
432[{"body":"CSRF mismatch","headers":{},"statusCode":403}]
5。我正在捕捉此错误并按照docs
中的说法执行/ csrfToken请求423["get",{"method":"get","headers":{},"data":{},"url":"/csrfToken"}]
433[{"body":{"_csrf":"49C5OVUZ-6SIL_zW3g1NGI87ux6Mlp-UJj_w"},"headers":{cut headers},"statusCode":200}]
6。尝试使用新令牌再次登录:
424["post",{"method":"post","headers":{},"data":{"_csrf":"49C5OVUZ-6SIL_zW3g1NGI87ux6Mlp-UJj_w","login":"alex","password":"123"},"url":"http://127.0.0.1:1337/login"}]
434[{"body":"CSRF mismatch","headers":{},"statusCode":403}]
我可以重复步骤5和6,结果相同。
如果我刷新页面,我可以毫无错误地登录。 问题是,发生了什么?为什么在步骤6中令牌不匹配?
编辑:退出方法:
req.session.destroy();
return res.send("ok");
编辑2:发送请求:
import socketIOClient from 'socket.io-client';
import sailsIOClient from 'sails.io.js';
var io = sailsIOClient(socketIOClient);
io.socket.post(form.action, serialize(form, {hash: true}), function (data, jwres){
...
});
答案 0 :(得分:2)
TL; DR:如果您通过套接字执行所有操作,请使用req.session.csrfSecret = null
代替req.session.destroy()
。
.destroy()
时,它会删除Express MemoryStore维护的{{1}}对象中当前会话ID(SID)的条目。通常情况下这很好,因为它会在下一个请求中重新生成,但这只是运行所有Express中间件的下一个请求 - 以及对Sails应用程序的Socket请求不要这样做,因为anyone trying to use Passport with Sails out-of-the-box会告诉你。因此,下次您发出套接字请求(生成新的CSRF密钥并获取新令牌)时,您实际上并未连接到会话,并且新信息也未保存。< / p>
如果不是销毁整个会话,而是销毁用于生成CSRF令牌的sessions
,那么下一个套接字请求仍会附加到会话中,并且将保存新的秘密。您还要删除保持用户登录的任何其他会话变量。