Skip to content

Instantly share code, notes, and snippets.

@Muqsit
Created June 7, 2020 06:04
Show Gist options
  • Select an option

  • Save Muqsit/6f28e2aad76b8276552d7e06e7dfdb3b to your computer and use it in GitHub Desktop.

Select an option

Save Muqsit/6f28e2aad76b8276552d7e06e7dfdb3b to your computer and use it in GitHub Desktop.
Xbox Live Web Authentication
<?php
declare(strict_types=1);
final class XboxLiveAPI{
private static function parseJsonResponse(string $response) : array{
$data = json_decode($response, true);
if(isset($data["error"])){
throw new ErrorException("{$data["error"]}: {$data["error_description"]}");
}
return $data;
}
/** @var string */
private $client_id;
/** @var string */
private $client_secret;
/** @var string */
private $redirect_uri;
/** @var string */
private $locale;
public function __construct(string $client_id, string $client_secret, string $redirect_uri, string $locale = "en-US"){
$this->client_id = $client_id;
$this->client_secret = $client_secret;
$this->redirect_uri = $redirect_uri;
$this->locale = $locale;
}
public function getRequestUrl() : string{
return "https://login.live.com/oauth20_authorize.srf?" . http_build_query([
"client_id" => $this->client_id,
"scope" => "XboxLive.signin",
"response_type" => "code",
"redirect_uri" => $this->redirect_uri,
"locale" => $this->locale
]);
}
/**
* Client is redirected to request_uri?code=code after they log in
* via getRequestUrl().
*
* @param string $code
* @return array<string, mixed>
*/
public function getAccessTokenInfo(string $code) : array{
$curl = curl_init("https://login.microsoftonline.com/consumers/oauth2/v2.0/token");
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query([
"grant_type" => "authorization_code",
"code" => $code,
"client_id" => $this->client_id,
"scope" => "XboxLive.signin",
"redirect_uri" => $this->redirect_uri,
"client_secret" => $this->client_secret
]));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
curl_close($curl);
if($result !== false){
return self::parseJsonResponse($result);
}
throw new RuntimeException("Failed to retrieve a response from Microsoft");
}
/**
* Access token can be retrieved from getAccessTokenInfo() (key = "access_token").
*
* @param string $access_token
* @return array<string, mixed>
* @throws ErrorException
*/
public function getAuthenticationInfo(string $access_token) : array{
$payload = json_encode([
"RelyingParty" => "http://auth.xboxlive.com",
"TokenType" => "JWT",
"Properties" => [
"AuthMethod" => "RPS",
"SiteName" => "user.auth.xboxlive.com",
"RpsTicket" => "d=" . $access_token,
]
]);
$curl = curl_init("https://user.auth.xboxlive.com/user/authenticate");
curl_setopt($curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($payload)
]);
curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
curl_close($curl);
if($result !== false){
return self::parseJsonResponse($result);
}
throw new RuntimeException("Failed to retrieve a response from Xbox Live Authentication host");
}
/**
* User token can be retrieved from getAuthenticationInfo() (key = "Token").
*
* @param string $user_token
* @return array
*/
public function getAuthorizationInfo(string $user_token) : array{
$payload = json_encode([
"RelyingParty" => "http://xboxlive.com",
"TokenType" => "JWT",
"Properties" => [
"UserTokens" => [$user_token],
"SandboxId" => "RETAIL"
]
]);
$curl = curl_init("https://xsts.auth.xboxlive.com/xsts/authorize");
curl_setopt($curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($payload)
]);
curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
curl_close($curl);
if($result !== false){
return self::parseJsonResponse($result);
}
throw new RuntimeException("Failed to retrieve a response from Xbox Live Xbox Live Authorization host");
}
}
@Muqsit
Copy link
Author

Muqsit commented Jun 7, 2020

Retrieving Client ID

Register an azure application at https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps.
image

Retrieving Client Secret

In your application, head over to Certificates & Secrets tab and click + New client secret.
image

Setting up Redirect URI

In your application, head over to Authentication tab and click + Add a platform.

Select Web and you will be asked to input Redirect URIs.
image

Fetching code from client login

Redirect client to XboxLiveAPI::getRequestUrl(). The client will be asked to sign in to their microsoft account. Once they do, they'll be redirected to $redirect_uri?code=code.

<?php
/**
 * @var string $client_id
 * @var string $client_secret
 * @var string $redirect_uri
 */
$api = new XboxLiveAPI($client_id, $client_secret, $redirect_uri);
?>
<html>
	<body>
		<a href="<?php echo $api->getRequestUrl(); ?>">Sign-In with Xbox Live</a>
	</body>
</html>

In the redirect_uri:

$code = $_GET["code"];

Fetching Xbox User ID from code

/**
 * @var string $client_id
 * @var string $client_secret
 * @var string $redirect_uri
 * @var string $code
 */
$api = new XboxLiveAPI($client_id, $client_secret, $redirect_uri);

$access_token_info = $api->getAccessTokenInfo($code);
$authentication_info = $api->getAuthenticationInfo($access_token_info["access_token"]);
$authorization_info = $api->getAuthorizationInfo($authentication_info["Token"]);

$xuid = $authorization_info["DisplayClaims"]["xui"][0]["xid"];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment