Twitch OAUTH2 implementation: "Client ID is missing"

I’m implementing the authorization grant flow here to collect the user’s Twitch ID, as well as their email (if they’ve used it to create/verify their account): Getting OAuth Access Tokens | Twitch Developers

However, after the authorization screen, I’ll receive this error when redirected back to my app:

{"error": "Unauthorized", "status": 401, "message": "Client ID is missing"}

I’ve registered a developer application to use the Twitch API, with the OAuth redirect URL as something like: https://.com/callback which matches what auto populates the URL during the redirect.

This is what my auth link looks like:

https://id.twitch.tv/oauth2/authorize?client_id=<client_id>&redirect_uri=<encoded https://<domain>.com/callback>&response_type=code&scope=user%3Aread%3Aemail&state=<state>

I’ve been using this as my Token URL- but not sure if I need to append client id, client secret and grant type (authorization_code) to it (I tried and it returned the same err):

https://id.twitch.tv/oauth2/token 

User URL:

https://api.twitch.tv/helix/users

Scope:

user:read:email

I’ve also tried every variation of client_id, Client-ID, client-Id etc. there is as I saw it on a few forums (but believe client_id is correct as that’s what’s in the dev docs).

When I follow the auth flow instructions here with curl: Getting OAuth Access Tokens | Twitch Developers , it does return:

{"access_token":"<access_token>","expires_in":14843,"refresh_token":"<refresh_token>","scope":["channel:manage:polls","channel:read:polls"],"token_type":"bearer"}

So which step is falling.

The POST to exchange a code for a token.
Or the call to users

I see no reference in your post to the code to toke exchange.

See Use the authorization code to get a token in the Getting OAuth Access Tokens | Twitch Developers

So to be clear

  • Step 1 Send the user to twitch - you are doing this step
  • Step 2 the user accepts (or declines) the account link - users are doing this step
  • Step 3 user is redirected to your callback URL with a ?code=
  • Step 4 exchange the ?code= for a token via a POST to https://id.twitch.tv/oauth2/token
  • Step 5 you should now have a response with an access token
  • Step 6 call users with your clientID and access token.

This “one page” example in PHP covers this flow - https://github.com/BarryCarlyon/twitch_misc/blob/main/authentication/user_access_generator/php/index.php

Step 1 is line 151 in the template which generates the URL
Step 3/4 is line 32 is the code to token exchange (this then self redirects to itself if successful to remove ?code from the URL to avoid F5 issues as code is one use)
Step 5 line 62 is the token storage into session
Step 6 linne 85 is token validate and users call.

In summary, you have an error, but you didn’t log which steps has failed.

Is is the code to token or the users API call?

oAuth URL’s are client_id
oAuth exchange is client_id
Headers in the /users/ call is client-id

1 Like

I think my code is failing somewhere between step 4 and step 5 - I’m not seeing the access token in my URL after I click authorize and right before it redirects back to my own app, as below:

https://id.twitch.tv/oauth2/authorize?client_id=<client_id>&redirect_uri=<redirect_uri>&response_type=code&scope=user%3Aread%3Aemail&state=<state>

I’ve got https://id.twitch.tv/oauth2/token in my code - but not https://id.twitch.tv/oauth2/validate or https://id.twitch.tv/oauth2/revoke if those are required?

At the callback is where I also receive a 302 err - my GET headers include only code, scope and state

The access token isn’t in the URL.

You send the user to this URL that you have shown.

Then they come backt your callback URL with a ?code= query string paramater somewhat like https://www.mycallback.com/login/?code=foo

Then you extract the code and exchange it for a token

You mean GET query parameters right?

Now you take this code and exchange it for a token.

see “Use the authorization code to get a token” in Getting OAuth Access Tokens | Twitch Developers

This in line 32 in my linked PHP example

        $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' => CLIENT_ID,
            'client_secret' => CLIENT_SECRET,
            'code' => $_GET['code'],
            'grant_type' => 'authorization_code',
            'redirect_uri' => REDIRECT_URI
        ));

This will exchange the code for an access token.

Revoke is my “logout of my site” function in this example

I have a validate function as a user can leave this example and come back in two days and the session is still valid. So you check the token is still valid and dump the session if it isn’t

You might not need these, this is just a full login/logout one page PHP example

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.