Home > database >  Twitter OAuth 2.0 responding with "Value passed for the token was invalid."
Twitter OAuth 2.0 responding with "Value passed for the token was invalid."

Time:10-13

EDIT: See solution. Problem was in how the Twitter library was instantiated.

I'm trying to get Twitter authorization using OAuth2. I'm able to get it to work in a simple test script, but when I try to use it in my WordPress plugin it doesn't work.

I'm using The PHP League's OAuth2 Client with a library I wrote to connect it to Twitter; the test script is in the README.

The test script stores the OAuth2 state in $_SESSION; the actual app stores it in a WordPress transient. I've confirmed the integrity of the data through the pipeline:

Data from Twitter library after generating auth URL:

Array
(
    [url] => https://twitter.com/i/oauth2/authorize?redirect_uri=https://smol.blog/wp-json/smolblog/v2/connect/callback/twitter&code_challenge=EV7BCVYmkvCnIlVLH6cVzrvjNloQlleAkkYwLLgg41w&code_challenge_method=S256&state=fd5824ef415aa325f1f68d3504bb16b3&scope=tweet.read users.read offline.access&response_type=code&approval_prompt=auto&client_id=MjVXMnRGVUN5Ym5lcVllcTVKZkk6MTpjaQ
    [state] => fd5824ef415aa325f1f68d3504bb16b3
    [verifier] => u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q
)

Data pulled from WordPress transient during the callback (stored slightly differently):

Array
(
    [id] => fd5824ef415aa325f1f68d3504bb16b3
    [userId] => 1
    [info] => Array
        (
                [verifier] => u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q
        )

)

Request object to Twitter's 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
                    (

                )

            )

    )

Body of said request:

client_id=MjVXMnRGVUN5Ym5lcVllcTVKZkk6MTpjaQ&client_secret=[redacted]&grant_type=authorization_code&code=aTVUMDkybzdsVmExOEQ5MjdrVjVOQVZ3YTVDbUdmTXRDMktZSzBaSGFqVk5LOjE2NjUzNjc1MjIyNjg6MToxOmFjOjE&code_verifier=u7Zbf1gVEFZLyTgr_2Hk~i5P2pt8VgicyhZgdeO0pAyIZqhSoYqglHaIxsNRjHz0AHpwhlU1~Q

The error:

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 actual app than there is in the test script, but I've verified the data at multiple points in the stack, including right before it's sent to Twitter. What else do I need to be testing, or is there something that I'm forgetting?

CodePudding user response:

Found the error. In the test script, the redirectUri was passed into the constructor of the OAuth2 client; In the app, it was passed into the getAuthorizationUrl function. This worked for the initial call to Twitter, but (apparently) that data is also needed for the getAccessToken call. So here's the fix.

Old and busted:

new Twitter([
    'clientId' => $app->env->twitterAppId ?? '',
    'clientSecret' => $app->env->twitterAppSecret ?? '',
])

New hotness:

new Twitter([
    'clientId' => $app->env->twitterAppId ?? '',
    'clientSecret' => $app->env->twitterAppSecret ?? '',
    'redirectUri' => "{$app->env->apiBase}connect/callback/twitter",
])
  • Related