编辑:查看解决方案。问题在于 Twitter 库的实例化方式。
我正在尝试使用 OAuth2 获取 Twitter 授权。我可以让它在一个简单的测试脚本中工作,但是当我尝试在我的 WordPress 插件中使用它时,它不起作用。
我正在使用 PHP League 的 OAuth2 客户端以及我编写的库来将其连接到 Twitter;测试脚本位于自述文件中。
测试脚本将OAuth2状态存储在$_SESSION中;实际的应用程序将其存储在 WordPress 瞬态中。我已经通过管道确认了数据的完整性:
生成 auth URL 后来自 Twitter 库的数据:
Array
(
[url] => https://twitter.com/i/oauth2/authorize?redirect_uri=https%3A%2F%2Fsmol.blog%2Fwp-json%2Fsmolblog%2Fv2%2Fconnect%2Fcallback%2Ftwitter&code_challenge=EV7BCVYmkvCnIlVLH6cVzrvjNloQlleAkkYwLLgg41w&code_challenge_method=S256&state=fd5824ef415aa325f1f68d3504bb16b3&scope=tweet.read%20users.read%20offline.access&response_type=code&approval_prompt=auto&client_id=MjVXMnRGVUN5Ym5lcVllcTVKZkk6MTpjaQ
[state] => fd5824ef415aa325f1f68d3504bb16b3
[verifier] => u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q
)
回调期间从 WordPress 瞬态提取的数据(存储方式略有不同):
Array
(
[id] => fd5824ef415aa325f1f68d3504bb16b3
[userId] => 1
[info] => Array
(
[verifier] => u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q
)
)
向 Twitter 令牌端点请求对象:
GuzzleHttp\Psr7\Request Object
(
[method:GuzzleHttp\Psr7\Request:private] => POST
[requestTarget:GuzzleHttp\Psr7\Request:private] =>
[uri:GuzzleHttp\Psr7\Request:private] => GuzzleHttp\Psr7\Uri Object
(
[scheme:GuzzleHttp\Psr7\Uri:private] => https
[userInfo:GuzzleHttp\Psr7\Uri:private] =>
[host:GuzzleHttp\Psr7\Uri:private] => api.twitter.com
[port:GuzzleHttp\Psr7\Uri:private] =>
[path:GuzzleHttp\Psr7\Uri:private] => /2/oauth2/token
[query:GuzzleHttp\Psr7\Uri:private] =>
[fragment:GuzzleHttp\Psr7\Uri:private] =>
[composedComponents:GuzzleHttp\Psr7\Uri:private] =>
)
[headers:GuzzleHttp\Psr7\Request:private] => Array
(
[Host] => Array
(
[0] => api.twitter.com
)
[content-type] => Array
(
[0] => application/x-www-form-urlencoded
)
[Authorization] => Array
(
[0] => Basic [base64-encoded app id and secret redacted]
)
)
[headerNames:GuzzleHttp\Psr7\Request:private] => Array
(
[content-type] => content-type
[host] => Host
[authorization] => Authorization
)
[protocol:GuzzleHttp\Psr7\Request:private] => 1.1
[stream:GuzzleHttp\Psr7\Request:private] => GuzzleHttp\Psr7\Stream Object
(
[stream:GuzzleHttp\Psr7\Stream:private] => Resource id #101
[size:GuzzleHttp\Psr7\Stream:private] =>
[seekable:GuzzleHttp\Psr7\Stream:private] => 1
[readable:GuzzleHttp\Psr7\Stream:private] => 1
[writable:GuzzleHttp\Psr7\Stream:private] => 1
[uri:GuzzleHttp\Psr7\Stream:private] => php://temp
[customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
(
)
)
)
上述请求的正文:
client_id=MjVXMnRGVUN5Ym5lcVllcTVKZkk6MTpjaQ&client_secret=[redacted]&grant_type=authorization_code&code=aTVUMDkybzdsVmExOEQ5MjdrVjVOQVZ3YTVDbUdmTXRDMktZSzBaSGFqVk5LOjE2NjUzNjc1MjIyNjg6MToxOmFjOjE&code_verifier=u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q
错误:
PHP Fatal error: Uncaught League\OAuth2\Client\Provider\Exception\IdentityProviderException: Value passed for the token was invalid. in /var/www/html/wp-content/plugins/smolblog-wp/vendor/smolblog/oauth2-twitter/src/Twitter.php:169
我知道我在这里错过了一些愚蠢的东西。但我一生都无法弄清楚什么。实际应用程序中的代码比测试脚本中的代码多得多,但我已经在堆栈中的多个点验证了数据,包括在将其发送到 Twitter 之前。我还需要测试什么,或者有什么我忘记了?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
发现错误。在测试脚本中,
redirectUri被传递到 OAuth2 客户端的构造函数中;在应用程序中,它被传递到getAuthorizationUrl函数中。这适用于对 Twitter 的初始调用,但(显然)getAccessToken调用也需要该数据。所以这是修复方法。又老又破:
new Twitter([ 'clientId' => $app->env->twitterAppId ?? '', 'clientSecret' => $app->env->twitterAppSecret ?? '', ])新热点:
new Twitter([ 'clientId' => $app->env->twitterAppId ?? '', 'clientSecret' => $app->env->twitterAppSecret ?? '', 'redirectUri' => "{$app->env->apiBase}connect/callback/twitter", ])