419注销和重新登录后Laravel中出现错误(多个选项卡)
我在我的Laravel应用程序中打开了两个选项卡 我在一个选项卡中单击“注销”。然后单击第二个选项卡中的“注销”。第二次419注销和重新登录后Laravel中出现错误(多个选项卡),laravel,csrf,Laravel,Csrf,我在我的Laravel应用程序中打开了两个选项卡 我在一个选项卡中单击“注销”。然后单击第二个选项卡中的“注销”。第二次logout用于给出419错误,但我将其添加到VerifyCsrfToken中间件的排除列表中。我不明白为什么我需要CSRF保护才能注销 但是,现在我有一个不同的问题 在两个选项卡中注销后,它们都位于登录页面上。现在,如果我尝试从第一个选项卡重新登录,就会出现419错误。从第二个选项卡,登录可以正常工作 我该怎么办?我不想在用户单击“登录”时向用户显示错误,这是糟糕的用户体验。
logout
用于给出419错误,但我将其添加到VerifyCsrfToken
中间件的排除列表中。我不明白为什么我需要CSRF保护才能注销
但是,现在我有一个不同的问题
在两个选项卡中注销后,它们都位于登录页面上。现在,如果我尝试从第一个选项卡重新登录,就会出现419错误。从第二个选项卡,登录可以正常工作
我该怎么办?我不想在用户单击“登录”时向用户显示错误,这是糟糕的用户体验。我也不想将登录路由排除在CSRF保护之外。注意事项
在这个回答中,我将浏览器打开的选项卡命名为选项卡A和选项卡B
只需考虑以下规则:
- 您的浏览器一次对域有一个活动会话(使用会话id cookie访问)
- 客户端:每个打开的选项卡都可以有一个CSRF标记,其形式为标题等
- 服务器端:会话变量中只保存一个csrf令牌
- 在每个post请求中,客户端和服务器令牌都应该匹配,否则会出现419错误
除了从CSRF保护中退出=['logout']
发生情景
1.
首先,您已经打开了选项卡A和B,它们已登录并共享相同的会话和令牌
选项卡A-会话1-令牌x
选项卡B-会话1-令牌x
2.
单击选项卡A注销。它将从服务器上清除会话。重定向回登录页面。在登录页面中,客户端请求服务器,为他创建一个新的会话和令牌
选项卡A-会话2-令牌y
选项卡B-会话2(会话id为“”的cookie用于域)-令牌x(客户端:在选项卡中显示/从服务器中删除,因为它在会话1中)
由于服务器端没有保存令牌x的会话1,因此选项卡B令牌与服务器的令牌y不匹配
3.
正在选项卡B上发送注销
如果您在启用csrf的情况下发送注销。中间件向您发送419,因为客户端上的令牌x和服务器上的令牌b之间存在误操作
如果其免于csrf,则它**清除服务器端的会话**,并将客户端重定向到登录页面,重定向后服务器使用新的csrf令牌为选项卡B创建一个新的会话
我想您可以在注销路径上免除csrf保护,然后继续第二个场景
选项卡A-会话3-令牌y
选项卡B-会话3-令牌z
如您所见,服务器具有会话3和令牌z。因此选项卡A不匹配
结论
正如您所看到的,出现这种错误有一些原因:
- 会话(cookie)是浏览器范围,但令牌是选项卡范围
- 用户在一个选项卡上做了一些事情,使得其他选项卡有一个错误处理其表单令牌的会话
- 打开多个选项卡
- 注销(重新创建会话)在一个选项卡上
- 继续使用其他打开的选项卡/表单(刷新可以解决此问题)
- 将注销功能更改为不清除会话只清除响应会话\u id
- 使用隐藏输入进行会话跟踪(其本身有向下的部分)(obsolote)
只需考虑以下规则:
- 您的浏览器一次对域有一个活动会话(使用会话id cookie访问)
- 客户端:每个打开的选项卡都可以有一个CSRF标记,其形式为标题等
- 服务器端:会话变量中只保存一个csrf令牌
- 在每个post请求中,客户端和服务器令牌都应该匹配,否则会出现419错误
除了从CSRF保护中退出=['logout']
发生情景
1.
首先,您已经打开了选项卡A和B,它们已登录并共享相同的会话和令牌
选项卡A-会话1-令牌x
选项卡B-会话1-令牌x
2.
单击选项卡A注销。它将从服务器上清除会话。重定向回登录页面。在登录页面中,客户端请求服务器,为他创建一个新的会话和令牌
选项卡A-会话2-令牌y
选项卡B-会话2(会话id为“”的cookie用于域)-令牌x(客户端:在选项卡中显示/从服务器中删除,因为它在会话1中)
由于服务器端没有会话1,它持有令牌x,因此选项卡B令牌m