Edit: View solution. The problem lies in the way the Twitter library is instantiated.
I'm trying to get Twitter authorization using OAuth2. I can get it working in a simple test script, but when I try to use it in my WordPress plugin, it doesn't work.
I'm using PHP League's OAuth2 client with a library I wrote to connect it to Twitter; the test script is in the readme file.
The test script stores OAuth2 state in $_SESSION
; the actual application stores it in a WordPress transient. I've confirmed the integrity of the data via the pipe:
Data from Twitter library after generating auth URL:
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 )
Data extracted from WordPress transient during callback (stored slightly differently):
Array ( [id] => fd5824ef415aa325f1f68d3504bb16b3 [userId] => 1 [info] => Array ( [verifier] => u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q ) )
Request the object from the Twitter token endpoint:
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 ( ) ) )
Text of the above request:
client_id=MjVXMnRGVUN5Ym5lcVllcTVKZkk6MTpjaQ&client_secret=[redacted]&grant_type=authorization_code&code=aTVUMDkybzdsVmExOEQ5MjdrVjVOQVZ3YTVDbUdmTXRDMktZSzBaSGFqVk5LOjE2NjUzNjc1MjIyNjg6MToxOmFjOjE&code_verifier=u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q
mistake:
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
I know I'm missing something stupid here. But I can't for the life of me figure out what. There's a lot more code in the real application than in the test script, but I've verified the data at multiple points in the stack, including before sending it to Twitter. Is there anything else I need to test, or is there something I'm forgetting?
found mistake. In the test script,
redirectUri
is passed into the OAuth2 client's constructor; in the application, it is passed into thegetAuthorizationUrl
function. This works for the initial call to Twitter, but (obviously) thegetAccessToken
call also requires that data. So here's the fix.Old and worn out:
New hot spots: