編輯:查看解決方案。問題在於 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 之前。我還需要測試什麼,或者有什麼我忘記了?
P粉1557104252023-12-17 00:47:56
發現錯誤。在測試腳本中,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", ])