CSRF 状态令牌与提供的 FB PHP SDK 3.1.1 Oauth 2.0 不匹配
我的服务器日志显示“CSRF 状态令牌与提供的令牌不匹配”错误,这似乎几乎每个用户都会发生。但是,用户已创建和/或经过身份验证,并且我能够检索用户信息。我正在使用带有 Apache 的 Linux 服务器。我也在使用最新的 Facebook PHP SDK v.3.1.1 谁能告诉我为什么会发生这种情况以及如何修复它?
My server logs show a "CSRF state token does not match one provided" error which seems to happen for almost every user. However, the users are created and/or authenticated and I am able to retrieve the user info. I am using a Linux server with Apache. I am also using the latest Facebook PHP SDK v.3.1.1 Can anyone tell me why this is happening and how to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
上周我遇到了类似的问题,并追踪到
state
字段被多次调用getLoginUrl()
覆盖。每次调用getLoginUrl()
时,SDK 中都会生成一个新的state
令牌,并将其存储在$_SESSION
中(它只是一个随机值) ),因此,如果您调用它两次并且用户使用第一个链接登录,则第二次调用将重置 SDK 的内部state
令牌,并且您将在日志中收到此错误。SDK 在 Facebook 授权用户并将其重定向回您的网站后返回的 URL 中查找相同的
state
令牌,如果不匹配,则会记录此错误(这里有一个链接来源)。I had a similar issue last week, and tracked it down to the
state
field being overwritten by multiple calls togetLoginUrl()
. Each time you callgetLoginUrl()
, a newstate
token is generated in the SDK and stored in the$_SESSION
(it's just a random value), so if you call it twice and the user uses the first link to log in, the second call will have reset the SDK's internalstate
token, and you will get this error in your logs.The SDK looks for the same
state
token in the URL coming back after Facebook authorizes the user and redirects them back to your site, and if it doesn't match it will log this error (here's a link to the source).Facebook SDK 代码在同一处理程序中两次检查令牌时存在错误。
我像这样编辑了 facebook.php 的 getCode 函数:
为了更加清晰,并且如果调用两次则不会声明无效令牌。
需要明确的是,该函数可以在同一个 url 处理程序中调用两次,例如:
$facebook->getUser();
然后在同一个处理程序中$facebook->getLogoutUrl()
然后getCode()
被调用两次,从而导致无效的错误消息Facebook SDK code has a bug when checking against tokens twice in the same handler.
I edited the getCode function of
facebook.php
like this:to be more clear and does not state invalid token if called twice.
To be clear the function can be called twice on the same url handler if eg:
$facebook->getUser();
and then in the same handler$facebook->getLogoutUrl()
then thegetCode()
is called twice thus resulting into and invalid error message好吧,我曾经遇到过这个问题,并且我遇到了
state
& 问题。 URL 中的code
参数 - 我的.htaccess
文件未转发它们。我猜你也有同样的问题。
CSRF 状态令牌与提供的令牌不匹配
希望如此帮助
Well, I've encountered this exact problem once, and I had a problem with the
state
&code
parameters in the URL - my.htaccess
file was not forwarding them.I'm guessing you are having the same problem.
CSRF state token does not match one provided
Hope this helps
为了在 chesles 的答案中添加一点,如果您像我一样使用 session_start() - session_write_close() 函数,则可能会出现此问题。
如果在请求 loginUrl 时没有启动会话,您将收到此错误。
旁注:为什么要停止会话呢?
使用会话的脚本会相互停止,因为它们正在等待会话数组可供使用。
想象一下,您有一个流行的应用程序,拥有数千名用户,并且有一个用于发布图片的操作(一个 php 脚本)。
像这样的事情:
--在脚本顶部启动会话
--连接到 facebook
--创建图像
--与 api 调用共享图像
--脚本结束,会话自动关闭
这样做,会话将被使用剧本无缘由地拖了好久。
小心这样的脚本,使用类似这样的脚本:
--在创建 facebook 对象之前启动会话
--connecting to facebook
--使用 session_write_close() 关闭会话,会话数组可用,其他脚本可以加载
--creating图像
--与 api 调用共享图像 /* 它认为这不需要会话。 */
--脚本结束,会话已手动关闭。
干杯。
To add a bit to chesles's answer, this problem can occur if you're playing with the session_start() - session_write_close() functions, as I did.
If there is no started session when you're requesting the loginUrl, you'll get this error.
Sidenote: Why bother stopping the session?
Scripts that use sessions stops each other, because they're waiting for the session array to be available to use.
Imagine that you have a popular application, with thousands of users, and have an action (a php script) where you post a picture.
Something like this:
--starting session at the top of the script
--connecting to facebook
--creating the image
--sharing the image with the api call
--script end, session closes automatically
Doing this, the session will be used by the script for a long time for no reason.
Be careful with such scripts, use something like this instead:
--starting session right before where you create the facebook object
--connecting to facebook
--closing session with session_write_close(), the session array's available, other scripts can load
--creating the image
--sharing the image with the api call /* It think this doesn't need a session. */
--script end, session already closed manually.
Cheers.
另一项注意事项 - 尽管 Facebook PHP API 文档中没有说明,但您必须为 PHP 会话配置 apache,登录过程才能正常工作。事实证明,这就是我们在获取“CSRF 状态令牌与提供的令牌不匹配”时遇到的问题。
确保您使用的服务器池已设置为使用 memcache 来获取会话信息,否则 apache 会将会话信息写入本地,如果下一个请求没有发送到同一台服务器,您将获得“CSRF 状态”令牌与提供的令牌不匹配”。
这是在开发环境(使用一台服务器)中非常有效但在生产中却失败的事情之一。
我们还必须重新配置 CDN 设置,以确保我们传递 PHP 会话 cookie。
One additional note - although it is not stated in the Facebook PHP API documentation, you have to have apache configured for PHP sessions for the login process to work. That turned out to be the problem we encountered when we were getting the "CSRF state token does not match one provided".
Make sure if you are using a server pool that you have it set up to use memcache for session information, otherwise apache will write the session information locally and if the next request doesn't go to the same server you will get the "CSRF state token does not match one provided".
This was one of those things that worked like a charm in a development environment (with one server) but failed in production.
We also had to reconfigure our CDN settings to make sure we were passing through the PHP Session cookie.
我有同样的问题。这很容易。 不要调用
之前
,否则您将收到“CSRF 状态令牌与提供的不匹配”错误。
I had the same issue. It´s easy. Don´t call
before
otherwise you will get "CSRF state token does not match one provided" error.
我在本地计算机上遇到了同样的问题,问题是我的 hosts 文件 阻止了与 Verisign 的通信,因此 Facebook 尝试与之通信的 URL (http://crl.verisign.com/pca3.crl)从未工作过(状态:404)。
从我的主机文件中注释掉各种 Verisign IP 地址就成功了!
I had the same problem in my local machine and the problem turned out to be that my hosts file was blocking communication with Verisign, so the URL Facebook tries to communicate with (http://crl.verisign.com/pca3.crl) never worked (state: 404).
Commenting out the various Verisign IP addresses from my hosts file did the trick!
CSRF 状态和代码是使用本地会话检查的,我敢打赌您需要检查 php.ini 中的 session.save_handler,以及它是否正常工作。
CSRF state and code are checked using local sessions, I bet you need to check your session.save_handler in your php.ini, and if it was working properly.
如果您在页面上使用 .htaccess mod 重写重定向,请在行末尾使用 [QSA](查询字符串附加)来保留 GET 变量,否则您会丢失 Facebook 登录所需的 $code 变量
if you use .htaccess mod rewrite redirects on your page, use the [QSA] (Query String Append) at the end of the lines to preserve the GET variables, or else you lost the $code variable, which is required to the facebook login