400 - Invalid authorization code

Sorry I know you have plenty of these same topics and I read through them all and can’t seem to figure out what I missing.

Below is my code, but no matter what I do I can’t get past the "Invalid authorization code. The other posts mentioned the token being used already and invalid. I am getting the #access_token and immediately sending it to the backend to then get the access_token. As far as I can tell I am not doing it more than once.

Any ideas what I am missing?

       $ch = curl_init('https://id.twitch.tv/oauth2/token');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, array(
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'code' => $_POST['code'],
            'grant_type' => 'authorization_code',
            'redirect_uri' => $_POST['redirectUrl']
        ));

        $r = curl_exec($ch);
        // $i = curl_getinfo($ch);
        curl_close($ch);

        $response = json_decode($r, true);

        if ($response['status'] == 200) {
            $token = json_decode($r);

            if (json_last_error() == JSON_ERROR_NONE) {
                echo json_encode($token);
                exit;
            } else {
                $error = 'Failed to parse the JSON at code for token exchange';
            }
        } else {
            $error = 'An Error Occured at code for token exchange: ' . print_r($r, true);
            print_r($error);
        }

It sounds like you are mixing up the Implicit Grant flow, with the Auth Code flow.

With the Implicit flow, the user will be redirected to your redirect uri with an access token in the URL fragment, ie #access_token=..... That’s the token, there’s no further steps than that. That auth flow is designed for client-side auth as it lasts for about 60 days, but is not possible to refresh and as it’s a URL fragment the client doesn’t automatically pass it to the server, so it is more useful for client-side requests.

The Auth Code flow on the other hand is for server-side requests, when the user is redirected there would be a URL param containing the code, ie ?code=.... That code, being part of the url parameters, is accessible by your server when the user made the request and so the server can then exchange that code for an access token and refresh token. The access token will last about 4 hours but the refresh token will allow you to use the Refresh Token endpoint and so you can programmatically get new tokens without needing the user to go through the process again.

1 Like

And for this is a full example of the code/auth code flow to help

and

        // $i = curl_getinfo($ch);
        curl_close($ch);

        $response = json_decode($r, true);

        if ($response['status'] == 200) {
            $token = json_decode($r);

should be

        $i = curl_getinfo($ch);
        curl_close($ch);

        if ($i['http_code'] == 200) {
            $token = json_decode($r);

There isn’t a status field in the json decoded data

Thanks guys. You made me review the docs again and it was just that I was passing response_type=access_token instead of response_type=code..