注销并获取新的/ csrfToken后,SailsJS CSRF不匹配

时间:2015-10-02 13:06:18

标签: node.js websocket sails.js csrf

我正在创建单页应用程序。我已经创建了登录注销操作,它们工作正常。但是,如果用户注销并且不会在浏览器中刷新页面,则由于“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){
...
});

1 个答案:

答案 0 :(得分:2)

TL; DR:如果您通过套接字执行所有操作,请使用req.session.csrfSecret = null代替req.session.destroy()

<小时/> 这里的问题是Express sessions的工作方式。当您在其中一个上调用.destroy()时,它会删除Express MemoryStore维护的{​​{1}}对象中当前会话ID(SID)的条目。通常情况下这很好,因为它会在下一个请求中重新生成,但这只是运行所有Express中间件的下一个请求 - 以及对Sails应用程序的Socket请求不要这样做,因为anyone trying to use Passport with Sails out-of-the-box会告诉你。因此,下次您发出套接字请求(生成新的CSRF密钥并获取新令牌)时,您实际上并未连接到会话,并且新信息也未保存。

< / p>

如果不是销毁整个会话,而是销毁用于生成CSRF令牌的sessions,那么下一个套接字请求仍会附加到会话中,并且将保存新的秘密。您还要删除保持用户登录的任何其他会话变量。