注销并获取新/ csrfToken后,SailsJS CSRF不匹配
我正在创build单页面应用程序。 我创build了login注销操作,他们工作正常。 但是,如果用户注销并且不会刷新浏览器中的页面,则由于“CSRF不匹配”错误而无法再次login。
脚步:
1.在第一次加载页面时,csrf是view local:
<div class="app" id="app" data-csrf="<%= _csrf %>"></div>
2.用户使用此令牌成功login:
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.如果他再次尝试login,他会发现“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.我正在捕获这个错误,并按照文档中的说法执行/ csrfToken请求
423["get",{"method":"get","headers":{},"data":{},"url":"/csrfToken"}] 433[{"body":{"_csrf":"49C5OVUZ-6SIL_zW3g1NGI87ux6Mlp-UJj_w"},"headers":{cut headers},"statusCode":200}]
6.尝试使用新令牌重新login:
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。
如果我刷新页面,我可以无误地login。 问题是,发生了什么事? 为什么步骤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){ ... });
TL; DR:使用req.session.csrfSecret = null
而不是req.session.destroy()
如果你正在做所有的套接字。
这里的问题是Express会话的工作方式。 当您调用.destroy()
时,它会删除Express MemoryStore维护的sessions
对象中当前会话标识(SID)的条目。 通常情况下,这很好,因为它会在下一个请求中重新生成,但这只是运行所有Express中间件的下一个请求 – 并且对Sails应用的Socket请求不会这样做,因为任何尝试使用Sails的Passport这个盒子会告诉你的。 所以下一次你发出一个套接字请求(产生一个新的CSRF秘密并获得一个新的令牌),你实际上并没有连接到一个会话,新的信息不会被保存。
如果不是销毁整个会话,而只是销毁用于生成CSRF令牌的csrfSecret
,则下一个套接字请求仍将附加到会话中,新的密钥将被保存。 您还需要清除保留用户login的任何其他会话variables。