Twitch Oauth Login Failure (Error 500)

The following script was written by someone far more competent than me 2 and a half years ago and it’s been working up until today when I’m now getting a 500 response when trying to login via Twitch, I’ve also tried it with our bot’s account and my partner’s account on his machine and it’s got the same problem. The only alterations I’ve made are to the streamer and moderator scopes, the last change was made a couple of months ago to add the ‘moderator:manage:announcements’ scope and there were no issues with that change at the time. Our entire setup requires this to work so I could be hugely appreciative of a speedy response.

> <?php
> // Provides $clientid and $secret (plus other configuration) for this script
> require_once('secret.php');
> 
> // util functions for getting URL contents
> require_once('utils.php');
> 
> $some_name = session_name("some_name");
> session_set_cookie_params(0, '/', '.shamblingincompetence.com');
> session_start();
> 
> /////////////////////////////////////////////////////////////////////////////
> // Start of OAUTH processing to get the user token
> //
> // Make sure that the session state returned matches the one saved
> if (isset($_SESSION['auth_state']) and isset($_GET['state']) and $_SESSION['auth_state']==$_GET['state']) {
> 
> 	// Check whether verbose authentication process was enabled
> 	$verbose=isset($_GET['verbose']) || isset($_SESSION['verbose']);
> 
> 	if($verbose) {
> 		echo "<pre>\nNote: Redirecting in 10 seconds to: " . $_SESSION['auth_redirect'] . "\n\n"; 
> 		echo "\$_GET:\n";
> 		var_dump($_GET);
> 		echo "\n \$_SESSION:\n";
> 		var_dump($_SESSION);
> 		echo "\n\n";
> 	}
> 
> 	// Use authorization code to get the user's access token.
>     $fields=array(
>                 'client_id' => $clientid,
>                 'client_secret' => $secret,
>                 'code' => $_GET['code'],
>                 'grant_type' => 'authorization_code',
>                 'redirect_uri' => urlencode($redirect_uri)
>             );
> 	$result = curl_post($tokenurl, $fields);
> 
>     $response=json_decode($result);
> 
> 	if($verbose) { var_dump($response); echo "\n";}
> 	
> 	if (!isset($response->access_token)) auth_error('No Access Token returned');	
>         $auth_token=$response->access_token;
> 	$_SESSION['user_token'] = $auth_token;
>         $_SESSION['client_id'] = $clientid;
> 	
> 	$date = new DateTime(NULL, new DateTimeZone( "UTC" ));
> 	$date->modify('+'.$response->expires_in.' seconds');
> 	$_SESSION['refresh_token'] = $response->refresh_token;
> 	$_SESSION['token_expires'] = $date->getTimeStamp();
> 	$_SESSION['token_expires_readable'] = $date->format('Y-m-d H:i:s T');
> 	
> 	//////////////////////////////////////////////////////////////////
> 	// OAUTH process completed, token now available for further usage
> 	//////////////////////////////////////////////////////////////////
> 
> 	// Get the User ID and Display Name from API
> 	// https://dev.twitch.tv/docs/api/reference#get-users
> 	// GET https://api.twitch.tv/helix/users
>         $header=array(
>             'Authorization: Bearer '.$auth_token, 
>             'Client-ID: '.$clientid
>         );
>         $result = curl_header($api_url.'users', $header);
>         $response=json_decode($result);
> 
> 	if($verbose) { var_dump($response); echo "\n";}
> 
>     if (!isset($response->data[0]->id)) auth_error('No User ID returned');
>     if (!isset($response->data[0]->display_name)) auth_error('No User display name returned');
> 
> 	// Are they the streamer?
> 	if($response->data[0]->id == $streamerID) {
> 		if($_GET['scope'] == $scopes_req) {
> 			// Let's re-auth with a request to access subscribers
> 			
> 			// Clear out session data
> 			unset($_SESSION['user_token']);
> 			unset($_SESSION['refresh_token']);
> 			unset($_SESSION['token_expires']);
> 			unset($_SESSION['token_expires_readable']);
> 			
> 			$state=uniqid();
> 			$_SESSION['auth_state']=$state;
> 			session_write_close();
> 			header(
> 				'Location:'.$oauthurl
> 				.'?response_type=code&redirect_uri='.urlencode($redirect_uri)
> 				.'&client_id='.$clientid.'&scope='.urlencode('channel:read:subscriptions bits:read channel:read:redemptions channel:moderate whispers:read channel:manage:redemptions channel:manage:broadcast user:read:email user:edit:broadcast clips:edit channel:manage:schedule moderator:manage:chat_settings moderator:manage:announcements moderator:read:chatters').'&state='.$state
> 			);
> 			exit();
> 		}
> 	} elseif ($response->data[0]->id == '543809818') {
> 		if($_GET['scope'] == $scopes_req) {
> 			unset($_SESSION['user_token']);
> 			unset($_SESSION['refresh_token']);
> 			unset($_SESSION['token_expires']);
> 			unset($_SESSION['token_expires_readable']);
> 			
> 			$state=uniqid();
> 			$_SESSION['auth_state']=$state;
> 			session_write_close();
> 			header(
> 				'Location:'.$oauthurl
> 				.'?response_type=code&redirect_uri='.urlencode($redirect_uri)
> 				.'&client_id='.$clientid.'&scope='.urlencode('channel:read:subscriptions bits:read channel:read:redemptions channel:moderate whispers:read channel:manage:redemptions channel:manage:broadcast user:read:email user:edit:broadcast clips:edit channel:manage:schedule moderator:manage:chat_settings moderator:manage:announcements').'&state='.$state
> 			);
> 			exit();
> 		}		
> 	}
> 	
> 	$_SESSION['user_id']=$response->data[0]->id;
> 	$_SESSION['user_name']=$response->data[0]->display_name;
> 	
> 	// Prepare MYSQL connection:
> // removed our db login which goes here for obvious reasons, but I'm confident it is not the cause of the issue
> 	
> 	$conn = new mysqli($servername, $username, $password, $dbname);
> 	if ($conn->connect_error) {
> 	  die("Connection failed: " . $conn->connect_error);
> 	}
> 	
> 	if($_SESSION['user_id'] == $streamerID) {
> 		// Store auth token in database
> 		$sql = "INSERT INTO ".$sqltblname." (token, refresh_token, expires) VALUES ('".$_SESSION['user_token']."', '".$_SESSION['refresh_token']."', '".$_SESSION['token_expires']."')";
> 		if($verbose) {echo $sql."\n";}
> 		$result = $conn->query($sql);
> 		if($verbose) {var_dump($result); echo "\n";}
> 		
> 		$_SESSION['subscriber'] = true;
> 		$_SESSION['subscriber_tier'] = 3000;
> 		$_SESSION['follower'] = true;
> 			
> 	} else {
> 		// Are they a follower?
> 		// https://dev.twitch.tv/docs/api/reference#get-users-follows
> 		// GET https://api.twitch.tv/helix/users/follows?from_id=<user ID>	
> 		$result = curl_header($api_url.'users/follows?from_id='.$_SESSION['user_id'].'&to_id='.$streamerID, $header);
>                 $response=json_decode($result);
> 	
> 		if($verbose) { var_dump($response); echo "\n"; }
> 	
> 		$_SESSION['follower'] = (isset($response->total) && ($response->total == 1));
> 		
> 		// Are they a subscriber?
> 		$sql = "SELECT * FROM ".$sqltblname." ORDER BY expires DESC LIMIT 1";
> 		if($verbose) {echo $sql."\n";}
> 		$result = $conn->query($sql);
> 		if($verbose) {var_dump($result); echo "\n";}
> 
> 		$date = new DateTime(NULL, new DateTimeZone( "UTC" ));
> 		$subtok = "";
> 		$subref = "";
> 		$subexp = "";
> 		if ($result->num_rows > 0) {
> 			while($row = $result->fetch_assoc()) {
>                             	if($verbose) {echo "Row data \n"; var_dump($row); echo "\n";}
> 				$subtok = $row['token'];
> 				$subref = $row['refresh_token'];
> 				$subexp = $row['expires'];
> 			}
> 		} else {
> 			auth_error('Streamer Auth Data not in the database');
> 		}
> 		
> 		if($subexp < $date->getTimeStamp()) {
> 			// Need to refresh token
> 			// Use authorization code to get the user's access token.
> 			$fields=array(
> 				'client_id' => $clientid,
> 				'client_secret' => $secret,
> 				'refresh_token' => $subref,
> 				'grant_type' => 'refresh_token',
> 				'redirect_uri' => urlencode($redirect_uri)
> 			);
> 			$result = curl_post($tokenurl, $fields);
> 			
> 			$response=json_decode($result);
> 			
> 			if($verbose) { var_dump($response); echo "\n";}
> 			
> 			if (!isset($response->access_token)) auth_error('Failed to refresh streamer token');
> 			$oldtok = $subtok;
> 			$subtok = $response->access_token;
> 			$subref = $response->refresh_token;
> 			$date->modify('+'.$response->expires_in.' seconds');
> 			$subexp = $date->getTimeStamp();
> 			
> 			$sql = "UPDATE ".$sqltblname." SET token = '".$subtok."', refresh_token = '".$subref."', expires = '".$subexp."' WHERE token = '".$oldtok."'";
> 			if($verbose) {echo $sql."\n";}
> 			$result = $conn->query($sql);
> 			if($verbose) {var_dump($result); echo "\n";}
> 		}
> 		
> 		// Check whether current user is subscribed to the streamer
> 		// https://dev.twitch.tv/docs/api/reference#get-broadcaster-subscriptions
> 		// GET https://api.twitch.tv/helix/subscriptions?broadcaster_id=<StreamerID>&user_id=<user ID>
> 		$streamerheader = array(
> 				'Authorization: Bearer '.$subtok, 
> 				'Client-ID: '.$clientid
> 			);
> 		
> 		$result = curl_header($api_url.'subscriptions?user_id='.$_SESSION['user_id'].'&broadcaster_id='.$streamerID, $streamerheader);
> 	    $response=json_decode($result);
> 	
> 		if($verbose) { var_dump($response); echo "\n"; }
> 	
> 		if(isset($response->data) && (count($response->data) == 1)) {
> 			$_SESSION['subscriber'] = true;
> 			$_SESSION['subscriber_tier'] = $response->data[0]->tier;
> 		} else {
> 			$_SESSION['subscriber'] = false;
> 			$_SESSION['subscriber_tier'] = 0;
> 		}
> 	}
> 	
> 	// Close session and redirect to original page	
> 	if (!isset($_SESSION['auth_redirect'])) auth_error('No return URL');
> 	$return_page = $_SESSION['auth_redirect'];
> 	
> 	// Clear out no longer needed items from the session
> 	unset($_SESSION['auth_redirect']);
> 	unset($_SESSION['auth_state']);
> 	session_write_close();
> 
> 	if($verbose) {
> 		echo "\n";
> 		var_dump($_SESSION);
> 		header('Refresh: 10; URL='. $return_page);
> 	} else {
> 		header('Location:'. $return_page);
> 	}
> } else {
>     echo "<pre>\nState is wrong. Did you make sure to actually hit the login url first?\nYou will be redirected to <a href=" . $mainsite . ">" . $mainsite . "</a> shortly\n\n";
> 	var_dump($_GET);
> 	echo "\n";
> 	var_dump($_SESSION);
> 	header('Refresh: 30; URL='. $mainsite);
> }
> exit();
> 
> /////////////////////////////////////////////////////////////////////////////
> // Support functions below this point
> 
> // Error function
> function auth_error($error_message)
> {
> 	print "There's been an error - " . $error_message;
> 	error_log($error_message);
> 	exit();
> }
> ?>

oAuth is currently down

it is being investigated

1 Like

So it’s a Twitch end issue?

1 Like

yes

500 server error = the server f**ked up

1 Like

Thank you for letting me know - I feel slightly less panicked now, although I’m not sure how we’re going to get stream up and running tomorrow!