Si solo desea obtener la identificación de usuario, el nombre y la imagen de Google para un visitante de su aplicación web, aquí está mi solución de servicio PHP pura para el año 2020 sin bibliotecas externas utilizadas -
Si lee la guía Uso de OAuth 2.0 para aplicaciones de servidor web de Google (y tenga cuidado, a Google le gusta cambiar los enlaces a su propia documentación), entonces solo debe realizar 2 pasos:
- Presentar al visitante una página web solicitando el consentimiento para compartir su nombre con su aplicación web.
- Luego, tome el "código" pasado por la página web anterior a su aplicación web y obtenga un token (en realidad 2) de Google.
Uno de los tokens devueltos se llama "id_token" y contiene la identificación del usuario, el nombre y la foto del visitante.
Aquí está el código PHP de un juego web mío. Inicialmente estaba usando Javascript SDK, pero luego me di cuenta de que los datos de usuario falsos se podían pasar a mi juego web, cuando solo usaba el SDK del lado del cliente (especialmente la identificación de usuario, que es importante para mi juego), así que cambié a usar PHP en el lado del servidor:
<?php
const APP_ID = '1234567890-abcdefghijklmnop.apps.googleusercontent.com';
const APP_SECRET = 'abcdefghijklmnopq';
const REDIRECT_URI = 'https://the/url/of/this/PHP/script/';
const LOCATION = 'Location: https://accounts.google.com/o/oauth2/v2/auth?';
const TOKEN_URL = 'https://oauth2.googleapis.com/token';
const ERROR = 'error';
const CODE = 'code';
const STATE = 'state';
const ID_TOKEN = 'id_token';
# use a "random" string based on the current date as protection against CSRF
$CSRF_PROTECTION = md5(date('m.d.y'));
if (isset($_REQUEST[ERROR]) && $_REQUEST[ERROR]) {
exit($_REQUEST[ERROR]);
}
if (isset($_REQUEST[CODE]) && $_REQUEST[CODE] && $CSRF_PROTECTION == $_REQUEST[STATE]) {
$tokenRequest = [
'code' => $_REQUEST[CODE],
'client_id' => APP_ID,
'client_secret' => APP_SECRET,
'redirect_uri' => REDIRECT_URI,
'grant_type' => 'authorization_code',
];
$postContext = stream_context_create([
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($tokenRequest)
]
]);
# Step #2: send POST request to token URL and decode the returned JWT id_token
$tokenResult = json_decode(file_get_contents(TOKEN_URL, false, $postContext), true);
error_log(print_r($tokenResult, true));
$id_token = $tokenResult[ID_TOKEN];
# Beware - the following code does not verify the JWT signature!
$userResult = json_decode(base64_decode(str_replace('_', '/', str_replace('-', '+', explode('.', $id_token)[1]))), true);
$user_id = $userResult['sub'];
$given_name = $userResult['given_name'];
$family_name = $userResult['family_name'];
$photo = $userResult['picture'];
if ($user_id != NULL && $given_name != NULL) {
# print your web app or game here, based on $user_id etc.
exit();
}
}
$userConsent = [
'client_id' => APP_ID,
'redirect_uri' => REDIRECT_URI,
'response_type' => 'code',
'scope' => 'profile',
'state' => $CSRF_PROTECTION,
];
# Step #1: redirect user to a the Google page asking for user consent
header(LOCATION . http_build_query($userConsent));
?>
Puede usar una biblioteca PHP para agregar seguridad adicional verificando la firma JWT. Para mis propósitos fue innecesario, porque confío en que Google no traicionará mi pequeño juego web enviando datos de visitantes falsos.
Además, si desea obtener más datos personales del visitante, necesita un tercer paso:
const USER_INFO = 'https://www.googleapis.com/oauth2/v3/userinfo?access_token=';
const ACCESS_TOKEN = 'access_token';
# Step #3: send GET request to user info URL
$access_token = $tokenResult[ACCESS_TOKEN];
$userResult = json_decode(file_get_contents(USER_INFO . $access_token), true);
O puede obtener más permisos en nombre del usuario: consulte la lista larga en el documento OAuth 2.0 Scopes for Google API .
Finalmente, las constantes APP_ID y APP_SECRET utilizadas en mi código, las obtienes de la consola API de Google :