En este documento, se explica cómo las aplicaciones de servidor web usan las bibliotecas cliente de las APIs de Google o las Extremos de OAuth 2.0 para implementar la autorización de OAuth 2.0 y acceder la API de datos de YouTube.
OAuth 2.0 permite a los usuarios compartir datos específicos con una aplicación y, al mismo tiempo, mantiene nombres de usuario, contraseñas y otra información privada. Por ejemplo, una aplicación puede usar OAuth 2.0 para obtener permiso para recuperar los datos de YouTube de un canal.
Este flujo de OAuth 2.0 está destinado específicamente a la autorización del usuario. Se diseñó para aplicaciones que puede almacenar información confidencial y mantener el estado. Un servidor web debidamente autorizado aplicación puede acceder a una API mientras el usuario interactúa con la aplicación o después de que este salió de la aplicación.
Las aplicaciones de servidor web a menudo también usan de servicio para autorizar solicitudes a la API, en especial cuando se llama a las APIs de Cloud para acceder datos basados en proyectos en lugar de datos específicos del usuario. Las aplicaciones de servidor web pueden usar junto con la autorización de usuarios.
La API de transmisión en directo de YouTube no es compatible con el flujo de la cuenta de servicio. Como no hay forma
vincular una cuenta de servicio a una cuenta de YouTube, los intentos de autorizar solicitudes con este flujo
genera un error NoLinkedYouTubeAccount
.
Bibliotecas cliente
En los ejemplos específicos para cada lenguaje de esta página, se usan Bibliotecas cliente de las APIs de Google para implementar Autorización de OAuth 2.0. Para ejecutar las muestras de código, primero debes instalar el biblioteca cliente para tu lenguaje.
Cuando usas una biblioteca cliente de la API de Google para controlar el flujo de OAuth 2.0 de tu aplicación, el cliente biblioteca realiza muchas acciones que la aplicación debería administrar por su cuenta. Para por ejemplo, determina cuándo la aplicación puede usar o actualizar los tokens de acceso almacenados, y cuando la aplicación debe volver a obtener el consentimiento. La biblioteca cliente también genera valores de redireccionamiento correctos URL y ayuda a implementar controladores de redireccionamiento que intercambien códigos de autorización por tokens de acceso.
Las bibliotecas cliente de la API de Google para aplicaciones del servidor están disponibles en los siguientes lenguajes:
Requisitos previos
Habilita las API para tu proyecto.
Cualquier aplicación que llame a las APIs de Google debe habilitarlas en el API Console
Para habilitar una API en tu proyecto, haz lo siguiente:
- Open the API Library en Google API Console
- If prompted, select a project, or create a new one.
- Usa la página Biblioteca para buscar y habilitar la API de datos de YouTube. Encuentra cualquier otra API que use tu aplicación y habilítalas también.
Crea credenciales de autorización
Cualquier aplicación que utilice OAuth 2.0 para acceder a las APIs de Google debe tener credenciales de autorización que identifican la aplicación en el servidor OAuth 2.0 de Google. Los siguientes pasos explican cómo crear credenciales para tu proyecto. Así, tus aplicaciones pueden usar las credenciales para acceder a las APIs que hayas habilitado para ese proyecto.
- Go to the Credentials page.
- Haz clic en Crear credenciales > ID de cliente de OAuth.
- Selecciona el tipo de aplicación Aplicación web.
- Completa el formulario y haz clic en Crear. Aplicaciones que usan lenguajes y frameworks
como PHP, Java, Python, Ruby y .NET deben especificar los URI de redireccionamiento autorizados. El
Los URI de redireccionamiento son los extremos a los que el servidor de OAuth 2.0 puede enviar respuestas. Estos
deben cumplir con las reglas de validación de Google.
Para realizar pruebas, puedes especificar URI que hagan referencia a la máquina local, como
http://localhost:8080
Teniendo esto en cuenta, ten en cuenta que todas las los ejemplos de este documento usanhttp://localhost:8080
como URI de redireccionamiento.Te recomendamos que diseñes los extremos de autenticación de tu app para que tu aplicación no exponga los códigos de autorización a otros recursos del .
Después de crear tus credenciales, descarga el archivo client_secret.json de la API ConsoleAlmacenar de forma segura el archivo en una ubicación que solo a la que puede acceder tu aplicación.
Identifica los permisos de acceso
Los permisos permiten que tu aplicación solo solicite acceso a los recursos que necesita, al tiempo que que les permite a los usuarios controlar el nivel de acceso que otorgan a tu aplicación. Por lo tanto, hay puede ser una relación inversa entre el número de alcances solicitados y la probabilidad de obtener el consentimiento del usuario.
Antes de que comiences a implementar la autorización de OAuth 2.0, te recomendamos que identifiques los alcances. a las que tu app necesitará permiso para acceder.
También recomendamos que tu aplicación solicite acceso a permisos de autorización mediante un de autorización incremental, en la que tu aplicación solicita acceso a datos del usuario en contexto. Esta práctica recomendada ayuda a los usuarios a comprender por qué tu aplicación necesita el acceso que solicita.
La versión 3 de la API de datos de YouTube utiliza los siguientes alcances:
Permisos | |
---|---|
https://www.googleapis.com/auth/youtube | Administrar tu cuenta de YouTube |
https://www.googleapis.com/auth/youtube.channel-memberships.creator | Ver una lista de los miembros actuales y activos de su canal, su nivel actual y el momento en que se hicieron miembros |
https://www.googleapis.com/auth/youtube.force-ssl | Vea, edite y borre de forma permanente sus videos, calificaciones, comentarios y subtítulos de YouTube |
https://www.googleapis.com/auth/youtube.readonly | Permite ver tu cuenta de YouTube. |
https://www.googleapis.com/auth/youtube.upload | Permite administrar tus videos de YouTube. |
https://www.googleapis.com/auth/youtubepartner | Ver y administrar sus elementos y el contenido asociado en YouTube |
https://www.googleapis.com/auth/youtubepartner-channel-audit | Permite ver información privada de tu canal de YouTube que sea relevante durante el proceso de auditoría con un socio de YouTube. |
El documento Alcances de la API de OAuth 2.0 contiene una lista completa de permisos que puedes usar para acceder a las APIs de Google.
Requisitos de lenguaje específico
Para ejecutar cualquiera de las muestras de código de este documento, necesitarás una Cuenta de Google, acceso a la Internet y un navegador web. Si usas una de las bibliotecas cliente de la API, consulta también la con los requisitos específicos de cada idioma a continuación.
PHP
Para ejecutar las muestras de código de PHP de este documento, necesitarás lo siguiente:
- PHP 5.6 o superior con la interfaz de línea de comandos (CLI) y la extensión JSON instaladas
- La herramienta de administración de dependencias Composer
-
La biblioteca cliente de las APIs de Google para PHP tiene las siguientes características:
composer require google/apiclient:^2.10
Python
Para ejecutar las muestras de código de Python en este documento, necesitarás lo siguiente:
- Python 2.6 o superior
- La herramienta de administración de paquetes pip.
- La biblioteca cliente de las APIs de Google para Python:
pip install --upgrade google-api-python-client
- Los objetos
google-auth
,google-auth-oauthlib
ygoogle-auth-httplib2
para la autorización del usuario.pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
- El framework de aplicaciones web de Flask en Python.
pip install --upgrade flask
- La biblioteca HTTP
requests
pip install --upgrade requests
Rita
Para ejecutar las muestras de código de Ruby en este documento, necesitarás lo siguiente:
- Ruby 2.6 o superior
-
La biblioteca de Google Auth para Ruby:
gem install googleauth
-
Framework de aplicación web de Sinatra Ruby.
gem install sinatra
Node.js
Para ejecutar las muestras de código de Node.js en este documento, necesitarás lo siguiente:
- La LTS de mantenimiento, la LTS activa o la versión actual de Node.js.
-
El cliente de Node.js de las APIs de Google:
npm install googleapis crypto express express-session
HTTP o REST
No necesitas instalar ninguna biblioteca para llamar directamente a OAuth 2.0 en los extremos.
Obtén tokens de acceso de OAuth 2.0
Los siguientes pasos muestran cómo interactúa tu aplicación con el servidor OAuth 2.0 de Google para obtener el consentimiento de un usuario para realizar una solicitud a la API en nombre del usuario. Tu aplicación debe tener para poder ejecutar una solicitud a la API de Google que requiera la autorización del usuario.
La siguiente lista resume rápidamente estos pasos:
- Tu aplicación identifica los permisos que necesita.
- Tu aplicación redirecciona al usuario a Google junto con la lista de solicitudes permisos.
- El usuario decide si otorga los permisos a tu aplicación.
- Tu aplicación averigua qué decidió el usuario.
- Si el usuario otorgó los permisos solicitados, tu aplicación recupera los tokens necesarios para lo siguiente: realizar solicitudes a la API en nombre del usuario.
Paso 1: Establece parámetros de autorización
El primer paso es crear la solicitud de autorización. Esa solicitud establece parámetros que identificar tu aplicación y definir los permisos que se le pedirá al usuario que otorgue tu aplicación.
- Si usas una biblioteca cliente de Google para la autenticación y autorización de OAuth 2.0, crear y configurar un objeto que defina estos parámetros.
- Si llamas directamente al extremo de Google OAuth 2.0, generarás una URL y establecerás el parámetros en esa URL.
Las pestañas que aparecen a continuación definen los parámetros de autorización admitidos para las aplicaciones de servidor web. El los ejemplos específicos del lenguaje también muestran cómo usar una biblioteca cliente o una biblioteca de autorización para configurar un objeto que establezca esos parámetros.
PHP
El siguiente fragmento de código crea un objeto Google\Client()
, que define la
parámetros en la solicitud de autorización.
Ese objeto usa información de tu archivo client_secret.json para identificar tu
y mantener la integridad de su aplicación. (Consulta Crea credenciales de autorización para obtener más información sobre
ese archivo). El objeto también identifica los permisos para los cuales tu aplicación solicita permiso.
para acceder y la URL al extremo de autenticación de tu aplicación, que manejará la respuesta desde
Servidor OAuth 2.0 de Google Por último, el código establece los objetos access_type
opcionales y
Parámetros include_granted_scopes
.
Por ejemplo, para solicitar acceso sin conexión a fin de recuperar los datos de YouTube de un usuario:
$client = new Google\Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfig('client_secret.json'); // Required, to set the scope value, call the addScope function $client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL); // Required, call the setRedirectUri function to specify a valid redirect URI for the // provided client_id $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // Recommended, offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType('offline'); // Recommended, call the setState function. Using a state value can increase your assurance that // an incoming connection is the result of an authentication request. $client->setState($sample_passthrough_value); // Optional, if your application knows which user is trying to authenticate, it can use this // parameter to provide a hint to the Google Authentication Server. $client->setLoginHint('hint@example.com'); // Optional, call the setPrompt function to set "consent" will prompt the user for consent $client->setPrompt('consent'); // Optional, call the setIncludeGrantedScopes function with true to enable incremental // authorization $client->setIncludeGrantedScopes(true);
Python
En el siguiente fragmento de código, se usa el módulo google-auth-oauthlib.flow
para construir
la solicitud de autorización.
El código construye un objeto Flow
, que identifica tu aplicación con
información del archivo client_secret.json que descargaste después
crear credenciales de autorización. Ese objeto también identifica la
los permisos a los que tu aplicación solicita permiso para acceder y la URL a la dirección
auth, que controlará la respuesta del servidor OAuth 2.0 de Google. Por último, el código
Configura los parámetros opcionales access_type
y include_granted_scopes
.
Por ejemplo, para solicitar acceso sin conexión a fin de recuperar los datos de YouTube de un usuario:
import google.oauth2.credentials import google_auth_oauthlib.flow # Required, call the from_client_secrets_file method to retrieve the client ID from a # client_secret.json file. The client ID (from that file) and access scopes are required. (You can # also use the from_client_config method, which passes the client configuration as it originally # appeared in a client secrets file but doesn't access the file itself.) flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/youtube.force-ssl']) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. flow.redirect_uri = 'https://www.example.com/oauth2callback' # Generate URL for request to Google's OAuth 2.0 server. # Use kwargs to set optional request parameters. authorization_url, state = flow.authorization_url( # Recommended, enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Optional, enable incremental authorization. Recommended as a best practice. include_granted_scopes='true', # Optional, if your application knows which user is trying to authenticate, it can use this # parameter to provide a hint to the Google Authentication Server. login_hint='hint@example.com', # Optional, set prompt to 'consent' will prompt the user for consent prompt='consent')
Rita
Usa el archivo client_secrets.json que creaste para configurar un objeto cliente en tu y mantener la integridad de su aplicación. Cuando configuras un objeto de cliente, especificas los permisos que tu aplicación necesita junto con la URL que dirige al extremo auth de tu aplicación, que controlará la respuesta del servidor de OAuth 2.0.
Por ejemplo, para solicitar acceso sin conexión a fin de recuperar los datos de YouTube de un usuario:
require 'google/apis/youtube_v3' require "googleauth" require 'googleauth/stores/redis_token_store' client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json') scope = 'https://www.googleapis.com/auth/youtube.force-ssl' token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')
Tu aplicación usa el objeto cliente para realizar operaciones de OAuth 2.0, como generar las URLs de solicitudes de autorización y la aplicación de tokens de acceso a las solicitudes HTTP.
Node.js
El siguiente fragmento de código crea un objeto google.auth.OAuth2
, que define la
parámetros en la solicitud de autorización.
Ese objeto usa información de tu archivo client_secret.json para identificar tu aplicación. Para solicitas permisos a un usuario para recuperar un token de acceso y se lo redirecciona a la página de consentimiento. Para crear una URL de la página de consentimiento, haz lo siguiente:
const {google} = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI * from the client_secret.json file. To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state });
Nota importante: El refresh_token
solo se devuelve el primer
autorización. Más detalles
aquí.
HTTP o REST
El extremo de OAuth 2.0 de Google está en https://accounts.google.com/o/oauth2/v2/auth
. Esta
solo se puede acceder a él a través de HTTPS. Se rechazan las conexiones HTTP simples.
El servidor de autorización de Google admite los siguientes parámetros de cadena de consulta para sitios web aplicaciones del servidor:
Parámetros | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
client_id |
Obligatorio
El ID de cliente de tu aplicación. Puedes encontrar este valor en API Console Credentials page |
||||||||||||||||
redirect_uri |
Obligatorio
Determina a dónde redirecciona el servidor de la API una vez que el usuario completa la
de autorización. El valor debe coincidir exactamente con uno de los URI de redireccionamiento autorizados para
el cliente de OAuth 2.0, que configuraste en la configuración
API Console
Credentials pageSi este valor no coincide con una
URI de redireccionamiento autorizado para el Ten en cuenta que el esquema |
||||||||||||||||
response_type |
Obligatorio
Determina si el extremo de Google OAuth 2.0 muestra un código de autorización. Establece el valor del parámetro en |
||||||||||||||||
scope |
Obligatorio
R delimitado por espacios una lista de alcances que identifican los recursos a los que tu aplicación podría acceder en el nombre del usuario. Estos valores informan la pantalla de consentimiento que Google muestra al usuario. Los permisos permiten que tu aplicación solo solicite acceso a los recursos que necesita al mismo tiempo que permiten a los usuarios controlar el nivel de acceso que le otorgan a su y mantener la integridad de su aplicación. Por lo tanto, existe una relación inversa entre el número de alcances solicitados. y la probabilidad de obtener el consentimiento del usuario. La versión 3 de la API de datos de YouTube utiliza los siguientes alcances:
En el documento Alcances de la API de OAuth 2.0, se proporciona una lista completa de los permisos que puedes usar para acceder a las APIs de Google. Recomendamos que tu aplicación solicite acceso a los permisos de autorización en contexto siempre que sea posible. Solicitando acceso a los datos del usuario en contexto mediante la autorización incremental, ayudarás a los usuarios a comprender por qué tu aplicación necesita el acceso que solicita. |
||||||||||||||||
access_type |
Recomendado
Indica si tu aplicación puede actualizar los tokens de acceso cuando el usuario no está presente
en el navegador. Los valores válidos de los parámetros son Establece el valor en |
||||||||||||||||
state |
Recomendado
Especifica cualquier valor de cadena que tu aplicación use para mantener el estado entre tus
la solicitud de autorización
y la respuesta del servidor de autorización.
El servidor muestra el valor exacto que envías como un par Puedes usar este parámetro para varios fines, como dirigir al usuario a la
el recurso correcto en tu aplicación, enviar nonces y mitigar las solicitudes entre sitios
falsificación. Como tu |
||||||||||||||||
include_granted_scopes |
Opcional
Permite que las aplicaciones usen autorización incremental para solicitar acceso a permisos
de permisos en contexto. Si estableces el valor de este parámetro en |
||||||||||||||||
enable_granular_consent |
Opcional
La configuración predeterminada es Cuando Google habilita permisos detallados para una aplicación, este parámetro no ya no tengan ningún efecto. |
||||||||||||||||
login_hint |
Opcional
Si la aplicación sabe qué usuario intenta autenticarse, puede usar este parámetro. para proporcionar una sugerencia al servidor de autenticación de Google. El servidor usa la sugerencia para para simplificar el flujo de acceso, ya sea completando previamente el campo de correo electrónico en el formulario de acceso o la sesión de acceso múltiple adecuada. Establece el valor del parámetro en una dirección de correo electrónico o un identificador |
||||||||||||||||
prompt |
Opcional
Una lista de mensajes para el usuario delimitados por espacios y que distinguen mayúsculas de minúsculas. Si no especificas este parámetro, se le solicitará al usuario solo la primera vez que tu proyecto solicita acceso. Consulta Solicitar volver a dar el consentimiento para obtener más información. Los valores posibles son:
|
Paso 2: Redirecciona al servidor OAuth 2.0 de Google
Redireccionar al usuario al servidor OAuth 2.0 de Google para iniciar la autenticación de autorización y autorización. Por lo general, esto ocurre cuando tu aplicación necesita acceder por primera vez al de los datos del usuario. En el caso de la autorización incremental, esta también ocurre cuando tu aplicación necesita acceder por primera vez a recursos adicionales que aún no tienes permiso para acceder.
PHP
- Genera una URL para solicitar acceso al servidor OAuth 2.0 de Google:
$auth_url = $client->createAuthUrl();
- Redireccionar al usuario a
$auth_url
:header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
En este ejemplo, se muestra cómo redireccionar al usuario a la URL de autorización con el sitio web de Flask framework de aplicaciones:
return flask.redirect(authorization_url)
Rita
- Genera una URL para solicitar acceso al servidor OAuth 2.0 de Google:
auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
- Redireccionar al usuario a
auth_uri
Node.js
-
Usa la URL generada
authorizationUrl
del paso 1 Es el métodogenerateAuthUrl
para solicitar acceso al servidor OAuth 2.0 de Google. -
Redireccionar al usuario a
authorizationUrl
res.redirect(authorizationUrl);
HTTP/REST
Sample redirect to Google's authorization server
An example URL is shown below, with line breaks and spaces for readability. The URL requests
access to a scope that permits access to retrieve the user's YouTube data. It uses incremental
authorization (include_granted_scopes=true
) to ensure that the new access token
covers any scopes to which the user previously granted the application access. Several other
parameters are also set in the example.
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& client_id=client_id
Después de crear la URL de la solicitud, redirecciona al usuario a ella.
El servidor OAuth 2.0 de Google autentica al usuario y obtiene su consentimiento para tu para acceder a los permisos solicitados. La respuesta se envía a tu aplicación. con la URL de redireccionamiento que especificaste.
Paso 3: Google solicita el consentimiento del usuario
En este paso, el usuario decide si otorgará a tu aplicación el acceso solicitado. En este Google muestra una ventana de consentimiento con el nombre de tu aplicación y la API de Google. servicios a los que solicita permiso para acceder con las credenciales de autorización del usuario y un resumen de los permisos de acceso que se otorgarán. El el usuario puede dar su consentimiento para otorgar acceso a uno o más alcances solicitados por tu aplicación o rechazar la solicitud.
Tu aplicación no necesita hacer nada en esta etapa mientras espera la respuesta del Servidor OAuth 2.0 de Google que indica si se otorgó algún acceso Esa respuesta se explica en el siguiente paso.
Errores
Las solicitudes al extremo de autorización de OAuth 2.0 de Google pueden mostrar mensajes de error para el usuario. en lugar de los flujos esperados de autenticación y autorización. Códigos de error comunes y sugeridos del dispositivo se enumeran a continuación.
admin_policy_enforced
La Cuenta de Google no puede autorizar uno o más alcances solicitados debido a las políticas de su administrador de Google Workspace. Consulta el artículo de ayuda para administradores de Google Workspace Controla qué aplicaciones de terceros las apps internas acceden a los datos de Google Workspace para obtener más información sobre cómo un administrador puede restringir el acceso a todos los permisos o permisos restringidos hasta que se otorgue acceso explícitamente a tu ID de cliente de OAuth.
disallowed_useragent
El extremo de autorización se muestra dentro de un usuario-agente incorporado que Google no admite Políticas de OAuth 2.0
Android
Los desarrolladores de Android pueden encontrar este mensaje de error al abrir solicitudes de autorización en
android.webkit.WebView
En su lugar, los desarrolladores deberían usar bibliotecas de Android, como
Acceso con Google para Android o de OpenID Foundation
AppAuth para Android:
Los desarrolladores web pueden encontrar este error cuando una app para Android abre un vínculo web general en una usuario-agente incorporado y un usuario navega hasta el extremo de autorización de OAuth 2.0 de Google desde tu sitio. Los desarrolladores deben permitir que los vínculos generales se abran en el controlador de vínculos predeterminado de la un sistema operativo completo, que incluye Android App Links o la app de navegador predeterminada. El Pestañas personalizadas de Android biblioteca también es una opción admitida.
iOS
Los desarrolladores de iOS y macOS pueden encontrar este error cuando abren solicitudes de autorización en
WKWebView
En su lugar, los desarrolladores deberían usar bibliotecas de iOS, como
Acceso con Google para iOS o de OpenID Foundation
AppAuth para iOS:
Los desarrolladores web pueden encontrar este error cuando una app para iOS o macOS abre un vínculo web general en
un usuario-agente incorporado y un usuario navega al extremo de autorización de OAuth 2.0 de Google desde
tu sitio. Los desarrolladores deben permitir que los vínculos generales se abran en el controlador de vínculos predeterminado de la
un sistema operativo completo, que incluye
Vínculos universales
o la app de navegador predeterminada. El
SFSafariViewController
biblioteca también es una opción admitida.
org_internal
El ID de cliente de OAuth de la solicitud forma parte de un proyecto que limita el acceso a las Cuentas de Google en un específico Organización de Google Cloud. Para obtener más información sobre esta opción de configuración, consulta la Tipo de usuario del artículo de ayuda Configura tu pantalla de consentimiento de OAuth.
invalid_client
El secreto del cliente de OAuth es incorrecto. Revisa el Cliente de OAuth configuración, incluido el ID de cliente y el secreto que se usan para esta solicitud.
invalid_grant
Cuando se actualiza un token de acceso o se usa autorización incremental, es posible que el token haya vencido o se haya se invalidó. Vuelve a autenticar al usuario y pídele su consentimiento para obtener tokens nuevos. Si continúas para ver este error, asegúrate de que tu aplicación se configuró correctamente y de que usando los tokens y parámetros correctos en tu solicitud. De lo contrario, es posible que la cuenta de usuario se borró o inhabilitó.
redirect_uri_mismatch
El redirect_uri
pasado en la solicitud de autorización no coincide con un
Es el URI de redireccionamiento para el ID de cliente de OAuth. Revisa los URI de redireccionamiento autorizados en la
Google API Console Credentials page
El parámetro redirect_uri
puede hacer referencia al flujo fuera de banda de OAuth (OOB) que tiene
quedó obsoleto y ya no es compatible. Consulta las
guía de migración para actualizar tu
y la integración de datos.
invalid_request
Se produjo un error con la solicitud que hiciste. Esto puede deberse a varios motivos:
- La solicitud no tenía el formato correcto
- Faltaban parámetros obligatorios en la solicitud
- La solicitud usa un método de autorización que Google no admite. Verifica tu OAuth integración usa un método de integración recomendado
Paso 4: Controla la respuesta del servidor de OAuth 2.0
El servidor de OAuth 2.0 responde a la solicitud de acceso de tu aplicación mediante la URL especificada en la solicitud.
Si el usuario aprueba la solicitud de acceso, la respuesta contendrá un código de autorización. Si el usuario no aprueba la solicitud, la respuesta contiene un mensaje de error. El El código de autorización o el mensaje de error que se devuelve al servidor web aparecen en la consulta. una cadena, como se muestra a continuación:
Una respuesta de error:
https://oauth2.example.com/auth?error=access_denied
Una respuesta de código de autorización:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
Ejemplo de respuesta del servidor de OAuth 2.0
Para probar este flujo, haz clic en la siguiente URL de ejemplo, que solicita acceso de solo lectura para ver los metadatos de los archivos de tu unidad de Google Drive:
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& client_id=client_id
Después de completar el flujo de OAuth 2.0, se te debería redireccionar a
http://localhost/oauth2callback
, que probablemente generará una
Se produce un error 404 NOT FOUND
, a menos que tu máquina local entregue un archivo en esa dirección. El
proporciona más detalles sobre la información que se devuelve en el URI cuando el usuario
se te redireccionará a tu aplicación.
Paso 5: Intercambia el código de autorización para actualizar y acceder tokens
Una vez que el servidor web recibe el código de autorización, puede intercambiarlo. para un token de acceso.
PHP
Para intercambiar un código de autorización por un token de acceso, usa authenticate
.
método:
$client->authenticate($_GET['code']);
Puedes recuperar el token de acceso con el método getAccessToken
:
$access_token = $client->getAccessToken();
Python
En tu página de devolución de llamada, usa la biblioteca google-auth
para verificar la autorización
respuesta del servidor. Luego, usa el método flow.fetch_token
para intercambiar la autorización.
código en esa respuesta para un token de acceso:
state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/youtube.force-ssl'], state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store the credentials in the session. # ACTION ITEM for developers: # Store user's access and refresh tokens in your data store if # incorporating this code into your real app. credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes}
Rita
En tu página de devolución de llamada, usa la biblioteca googleauth
para verificar el servidor de autorización
respuesta. Usa el método authorizer.handle_auth_callback_deferred
para guardar
el código de autorización y redireccionarlo de nuevo a la URL que originalmente solicitó la autorización. Esta
aplaza el intercambio del código almacenando temporalmente los resultados en la sesión del usuario.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url
Node.js
Para intercambiar un código de autorización por un token de acceso, usa getToken
.
método:
const url = require('url'); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); });
HTTP o REST
Para intercambiar un código de autorización por un token de acceso, llama al
https://oauth2.googleapis.com/token
y establece los siguientes parámetros:
Campos | |
---|---|
client_id |
El ID de cliente obtenido de API Console Credentials page |
client_secret |
El secreto del cliente obtenido de API Console Credentials page |
code |
El código de autorización que se muestra en la solicitud inicial. |
grant_type |
Como se define en OAuth 2.0,
especificación, el valor de este campo se debe establecer en authorization_code . |
redirect_uri |
Uno de los URI de redireccionamiento que se enumeran para tu proyecto en la
API Console
Credentials page por el valor especificado
client_id |
En el siguiente fragmento, se muestra una solicitud de muestra:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=https%3A//oauth2.example.com/code& grant_type=authorization_code
Para responder a esta solicitud, Google muestra un objeto JSON que contiene un acceso de corta duración
y uno de actualización.
Ten en cuenta que el token de actualización solo se muestra si tu aplicación estableció el access_type
.
parámetro a offline
en la solicitud inicial a la
servidor de autorización.
La respuesta contiene los siguientes campos:
Campos | |
---|---|
access_token |
El token que envía la aplicación para autorizar una solicitud a la API de Google. |
expires_in |
La vida útil restante del token de acceso en segundos. |
refresh_token |
Un token que puedes usar para obtener un token de acceso nuevo. Los tokens de actualización son válidos hasta el
el usuario revoca el acceso.
Nuevamente, este campo solo está presente en esta respuesta si estableces access_type
parámetro a offline en la solicitud inicial al servidor de autorización de Google.
|
scope |
Los permisos de acceso otorgados por el access_token expresados como una lista de
cadenas delimitadas por espacios y que distinguen mayúsculas de minúsculas. |
token_type |
El tipo de token que se muestra. En este momento, el valor de este campo siempre está establecido en
Bearer |
En el siguiente fragmento, se muestra una respuesta de muestra:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/youtube.force-ssl", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Errores
Cuando intercambies el código de autorización por un token de acceso, es posible que encuentres lo siguiente: en lugar de la respuesta esperada. Los códigos de error comunes y las soluciones sugeridas que se enumeran a continuación.
invalid_grant
El código de autorización proporcionado no es válido o tiene un formato incorrecto. Solicita un código nuevo antes del reiniciar el proceso de OAuth para solicitar el consentimiento del usuario de nuevo.
Llama a las APIs de Google
PHP
Usa el token de acceso para llamar a las APIs de Google. Para ello, sigue estos pasos:
- Si necesitas aplicar un token de acceso a un objeto
Google\Client
nuevo, para Por ejemplo, si almacenaste el token de acceso en una sesión de usuario, usa el MétodosetAccessToken
:$client->setAccessToken($access_token);
- Compila un objeto de servicio para la API a la que deseas llamar. Creas un objeto Service
proporcionar un objeto
Google\Client
autorizado al constructor de la API que quieres llamar. Por ejemplo, para invocar la API de datos de YouTube:$youtube = new Google_Service_YouTube($client);
- Realizar solicitudes al servicio de API con el
que proporciona el objeto de servicio.
Por ejemplo, para utilizar la API de datos de YouTube para recuperar una lista de transmisiones en vivo de la
canal del usuario:
$broadcasts = $youtube->liveBroadcasts->listLiveBroadcasts('id,snippet', [ 'mine' => true ]);
Python
Después de obtener un token de acceso, tu aplicación puede usarlo para autorizar solicitudes de API en de una cuenta de usuario o de servicio determinada. Usa credenciales de autorización específicas del usuario para crear un objeto de servicio para la API a la que deseas llamar y, luego, usar ese objeto para de las solicitudes a la API autorizadas.
- Compila un objeto de servicio para la API a la que deseas llamar. Creas un objeto Service
Llamando al método
build
de la bibliotecagoogleapiclient.discovery
con el nombre y versión de la API y las credenciales de usuario: Por ejemplo, para invocar la versión 3 de la API de datos de YouTube:from googleapiclient.discovery import build youtube = build('youtube', 'v3', credentials=credentials)
- Realizar solicitudes al servicio de API con el
que proporciona el objeto de servicio.
Por ejemplo, para utilizar la API de datos de YouTube para recuperar una lista de transmisiones en vivo de la
canal del usuario:
broadcasts = youtube.liveBroadcasts().list(part='id,snippet', mine=True).execute()
Rita
Después de obtener un token de acceso, tu aplicación puede usarlo para realizar solicitudes a la API en de una cuenta de usuario o de servicio determinada. Usa credenciales de autorización específicas del usuario para crear un objeto de servicio para la API a la que deseas llamar y, luego, usar ese objeto para de las solicitudes a la API autorizadas.
- Compila un objeto de servicio para la API a la que deseas llamar.
Por ejemplo, para invocar la versión 3 de la API de datos de YouTube:
youtube = Google::Apis::YoutubeV3::YouTubeService.new
- Configura las credenciales en el servicio:
youtube.authorization = credentials
- Realizar solicitudes al servicio de API con el
interfaz
que proporciona el objeto Service.
Por ejemplo, para utilizar la API de datos de YouTube para recuperar una lista de transmisiones en vivo de la
canal del usuario:
broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)
Alternativamente, la autorización se puede proporcionar por método al proporcionar la
options
a un método:
broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)
Node.js
Después de obtener un token de acceso y configurarlo para el objeto OAuth2
, usa el objeto.
llamar a las APIs de Google. Tu aplicación puede usar ese token para autorizar solicitudes de API en nombre de
una cuenta de usuario o de servicio determinada. Compila un objeto de servicio para la API a la que deseas llamar.
const { google } = require('googleapis'); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } });
HTTP o REST
Luego de que la aplicación obtenga un token de acceso, puedes usarlo para realizar llamadas a un servicio
en nombre de un proveedor de servicios
de usuario si se otorgaron los permisos de acceso que requiere la API. Para ello, incluye
el token de acceso en una solicitud a la API mediante una consulta access_token
o un valor de encabezado HTTP Bearer
Authorization
. Cuando sea posible,
se prefiere el encabezado HTTP, ya que las cadenas de consulta tienden a ser visibles en los registros del servidor. En la mayoría
puedes usar una biblioteca cliente para configurar las llamadas a las APIs de Google (por ejemplo, cuando
Invoca la API de YouTube Live Streaming).
Ten en cuenta que la API de transmisión en directo de YouTube no es compatible con el flujo de la cuenta de servicio. Desde ese lugar
no existe forma de vincular una cuenta de servicio a una cuenta de YouTube, intenta autorizar solicitudes con esta
generará un error NoLinkedYouTubeAccount
.
Puedes probar todas las APIs de Google y ver sus alcances en la OAuth 2.0 Playground.
Ejemplos de solicitudes GET de HTTP
Un llamado a la
liveBroadcasts.list
extremo (la API de YouTube Live Streaming) con el HTTP Authorization: Bearer
el encabezado podría verse de la siguiente manera. Ten en cuenta que debes especificar tu propio token de acceso:
GET /youtube/v3/liveBroadcasts?part=id%2Csnippet&mine=true HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Esta es una llamada a la misma API para el usuario autenticado con access_token
.
Parámetro de cadena de consulta:
GET https://www.googleapis.com/youtube/v3/liveBroadcasts?access_token=access_token&part=id%2Csnippet&mine=true
Ejemplos de curl
Puedes probar estos comandos con la aplicación de línea de comandos de curl
. Este es un
ejemplo que usa la opción de encabezado HTTP (preferida):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/liveBroadcasts?part=id%2Csnippet&mine=true
Como alternativa, la opción de parámetro de cadena de consulta:
curl https://www.googleapis.com/youtube/v3/liveBroadcasts?access_token=access_token&part=id%2Csnippet&mine=true
Ejemplo completo
El siguiente ejemplo imprime un objeto con formato JSON que muestra transmisiones en vivo. para el canal de YouTube del usuario autenticado después de que el usuario autoriza el para recuperar esos datos.
PHP
Para ejecutar este ejemplo, haz lo siguiente:
- En API Console, agrega la URL de la máquina local al
lista de URLs de redireccionamiento. Por ejemplo, agrega
http://localhost:8080
. - Crea un directorio nuevo y cámbialo a él. Por ejemplo:
mkdir ~/php-oauth2-example cd ~/php-oauth2-example
- Instalar el cliente de la API de Google
Biblioteca para PHP con Composer:
composer require google/apiclient:^2.10
- Crea los archivos
index.php
yoauth2callback.php
con el contenido. a continuación. - Ejecuta el ejemplo con un servidor web configurado para entregar PHP. Si usas PHP 5.6 o una versión posterior,
pueden usar el servidor web de prueba integrado de PHP:
php -S localhost:8080 ~/php-oauth2-example
index.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); $client->setAuthConfig('client_secrets.json'); $client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL); if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); $youtube = new Google_Service_YouTube($client); $broadcasts = $youtube->liveBroadcasts->listLiveBroadcasts('id,snippet', [ 'mine' => true ]); echo json_encode($broadcasts); } else { $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); }
oauth2callback.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); $client->setAuthConfigFile('client_secrets.json'); $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); $client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL); if (! isset($_GET['code'])) { // Generate and set state value $state = bin2hex(random_bytes(16)); $client->setState($state); $_SESSION['state'] = $state; $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } else { // Check the state value if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) { die('State mismatch. Possible CSRF attack.'); } $client->authenticate($_GET['code']); $_SESSION['access_token'] = $client->getAccessToken(); $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); }
Python
En este ejemplo, se usa el marco de trabajo Flask. Integra
ejecuta una aplicación web en http://localhost:8080
que te permite probar OAuth 2.0.
de tu flujo de trabajo. Si vas a esa URL, deberías ver cuatro vínculos:
- Prueba una solicitud a la API: Este vínculo dirige a una página que intenta ejecutar una API de muestra. para cada solicitud. Si es necesario, inicia el flujo de autorización. Si se realiza de forma correcta, la página muestra respuesta de la API.
- Prueba el flujo de autenticación directamente: Este vínculo dirige a una página que intenta enviar al usuario. a través del flujo de autorización. La aplicación solicita permiso para enviar solicitudes autorizadas a la API en nombre del usuario
- Revocar credenciales actuales: este vínculo dirige a una página que revoca permisos que el usuario ya le otorgó a la aplicación.
- Borrar credenciales de sesión de Flask: Este vínculo borra las credenciales de autorización que son almacenados en la sesión de Flask. Esto te permite ver qué pasaría si un usuario que ya permiso a tu app intentó ejecutar una solicitud a la API en una sesión nueva. También te permite verás la respuesta de la API que tu app obtendría si un usuario le otorgara permisos a la y esta sigue intentando autorizar una solicitud con un token de acceso revocado.
# -*- coding: utf-8 -*- import os import flask import requests import google.oauth2.credentials import google_auth_oauthlib.flow import googleapiclient.discovery # This variable specifies the name of a file that contains the OAuth 2.0 # information for this application, including its client_id and client_secret. CLIENT_SECRETS_FILE = "client_secret.json" # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account and requires requests to use an SSL connection. SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl'] API_SERVICE_NAME = 'youtube' API_VERSION = 'v3' app = flask.Flask(__name__) # Note: A secret key is included in the sample so that it works. # If you use this code in your application, replace this with a truly secret # key. See https://flask.palletsprojects.com/quickstart/#sessions. app.secret_key = 'REPLACE ME - this value is here as a placeholder.' @app.route('/') def index(): return print_index_table() @app.route('/test') def test_api_request(): if 'credentials' not in flask.session: return flask.redirect('authorize') # Load credentials from the session. credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) youtube = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) broadcasts = youtube.liveBroadcasts().list(part='id,snippet', mine=True).execute() # Save credentials back to session in case access token was refreshed. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. flask.session['credentials'] = credentials_to_dict(credentials) return flask.jsonify(**broadcasts) @app.route('/authorize') def authorize(): # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES) # The URI created here must exactly match one of the authorized redirect URIs # for the OAuth 2.0 client, which you configured in the API Console. If this # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' # error. flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true') # Store the state so the callback can verify the auth server response. flask.session['state'] = state return flask.redirect(authorization_url) @app.route('/oauth2callback') def oauth2callback(): # Specify the state when creating the flow in the callback so that it can # verified in the authorization server response. state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES, state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) # Use the authorization server's response to fetch the OAuth 2.0 tokens. authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store credentials in the session. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. credentials = flow.credentials flask.session['credentials'] = credentials_to_dict(credentials) return flask.redirect(flask.url_for('test_api_request')) @app.route('/revoke') def revoke(): if 'credentials' not in flask.session: return ('You need to <a href="/authorize">authorize</a> before ' + 'testing the code to revoke credentials.') credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) revoke = requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'}) status_code = getattr(revoke, 'status_code') if status_code == 200: return('Credentials successfully revoked.' + print_index_table()) else: return('An error occurred.' + print_index_table()) @app.route('/clear') def clear_credentials(): if 'credentials' in flask.session: del flask.session['credentials'] return ('Credentials have been cleared.<br><br>' + print_index_table()) def credentials_to_dict(credentials): return {'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes} def print_index_table(): return ('<table>' + '<tr><td><a href="/test">Test an API request</a></td>' + '<td>Submit an API request and see a formatted JSON response. ' + ' Go through the authorization flow if there are no stored ' + ' credentials for the user.</td></tr>' + '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' + '<td>Go directly to the authorization flow. If there are stored ' + ' credentials, you still might not be prompted to reauthorize ' + ' the application.</td></tr>' + '<tr><td><a href="/revoke">Revoke current credentials</a></td>' + '<td>Revoke the access token associated with the current user ' + ' session. After revoking credentials, if you go to the test ' + ' page, you should see an <code>invalid_grant</code> error.' + '</td></tr>' + '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' + '<td>Clear the access token currently stored in the user session. ' + ' After clearing the token, if you <a href="/test">test the ' + ' API request</a> again, you should go back to the auth flow.' + '</td></tr></table>') if __name__ == '__main__': # When running locally, disable OAuthlib's HTTPs verification. # ACTION ITEM for developers: # When running in production *do not* leave this option enabled. os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # Specify a hostname and port that are set as a valid redirect URI # for your API project in the Google API Console. app.run('localhost', 8080, debug=True)
Rita
En este ejemplo, se usa el framework Sinatra.
require 'google/apis/youtube_v3' require 'sinatra' require 'googleauth' require 'googleauth/stores/redis_token_store' configure do enable :sessions set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json') set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback') end get '/' do user_id = settings.client_id.id credentials = settings.authorizer.get_credentials(user_id, request) if credentials.nil? redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request) end youtube = Google::Apis::YoutubeV3::YouTubeService.new broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true) "<pre>#{JSON.pretty_generate(broadcasts.to_h)}</pre>" end get '/oauth2callback' do target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url end
Node.js
Para ejecutar este ejemplo, haz lo siguiente:
-
En API Console, agrega la URL del elemento
máquina local a la lista de URL de redireccionamiento. Por ejemplo, agrega
http://localhost
- Asegúrate de tener LTS de mantenimiento, LTS activa o la versión actual de Se instaló Node.js.
-
Crea un directorio nuevo y cámbialo a él. Por ejemplo:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Install the
Google API Client
Library
for Node.js using npm:
npm install googleapis
-
Crea los archivos
main.js
con el siguiente contenido. -
Ejecuta el ejemplo:
node .\main.js
main.js
const http = require('http'); const https = require('https'); const url = require('url'); const { google } = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. * To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; /* Global variable that stores user credential in this code example. * ACTION ITEM for developers: * Store user's refresh token in your data store if * incorporating this code into your real app. * For more information on handling refresh tokens, * see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens */ let userCredential = null; async function main() { const app = express(); app.use(session({ secret: 'your_secure_secret_key', // Replace with a strong secret resave: false, saveUninitialized: false, })); // Example on redirecting user to Google's OAuth 2.0 server. app.get('/', async (req, res) => { // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state }); res.redirect(authorizationUrl); }); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); /** Save credential to the global variable in case access token was refreshed. * ACTION ITEM: In a production app, you likely want to save the refresh token * in a secure persistent database instead. */ userCredential = tokens; // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } }); } }); // Example on revoking a token app.get('/revoke', async (req, res) => { // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end(); }); const server = http.createServer(app); server.listen(80); } main().catch(console.error);
HTTP o REST
Este ejemplo de Python usa el marco de trabajo Flask y la biblioteca Requests para demostrar el OAuth 2.0. Recomendamos usar la biblioteca cliente de la API de Google para Python en este flujo. (El ejemplo en la pestaña Python usa la biblioteca cliente).
import json import flask import requests app = flask.Flask(__name__) CLIENT_ID = '123456789.apps.googleusercontent.com' CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl' REDIRECT_URI = 'http://example.com/oauth2callback' @app.route('/') def index(): if 'credentials' not in flask.session: return flask.redirect(flask.url_for('oauth2callback')) credentials = json.loads(flask.session['credentials']) if credentials['expires_in'] <= 0: return flask.redirect(flask.url_for('oauth2callback')) else: headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])} req_uri = 'https://youtube.googleapis.com/youtube/v3/liveBroadcasts' r = requests.get(req_uri, headers=headers) return r.text @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: state = str(uuid.uuid4()) flask.session['state'] = state auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI, SCOPE, state) return flask.redirect(auth_uri) else: if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']: return 'State mismatch. Possible CSRF attack.', 400 auth_code = flask.request.args.get('code') data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'} r = requests.post('https://oauth2.googleapis.com/token', data=data) flask.session['credentials'] = r.text return flask.redirect(flask.url_for('index')) if __name__ == '__main__': import uuid app.secret_key = str(uuid.uuid4()) app.debug = False app.run()
Reglas de validación de URI de redireccionamiento
Google aplica las siguientes reglas de validación al redireccionamiento de URI para ayudar a los desarrolladores mantener sus aplicaciones seguras. Los URI de redireccionamiento deben cumplir con estas reglas. Consulta Sección 3 RFC 3986 para el del dominio, el host, la ruta de acceso, la consulta, el esquema y la información del usuario, como se detalla a continuación.
Reglas de validación | |
---|---|
Esquema |
Los URI de redireccionamiento deben usar el esquema HTTPS, no el HTTP simple. Los URI de host local (incluidos los URI de la dirección IP de localhost) están exentos de esta regla. |
Host |
Los hosts no pueden ser direcciones IP sin procesar. Las direcciones IP de host local están exentas de esta regla. |
Dominio |
“googleusercontent.com” .goo.gl ), a menos que
la aplicación es propietaria del dominio. Además, si una app que posee un dominio de abreviación elige
redireccionamiento a ese dominio, ese URI de redireccionamiento debe contener
“/google-callback/” en su ruta de acceso o termina con
“/google-callback” |
Información del usuario |
Los URI de redireccionamiento no pueden contener el subcomponente userinfo. |
Ruta de acceso |
Los URI de redireccionamiento no pueden contener un recorrido de ruta de acceso (también llamado retroceso de directorio).
que se representa mediante |
Consulta |
Los URI de redireccionamiento no pueden contener redireccionamientos abiertos. |
Fragmento |
Los URI de redireccionamiento no pueden contener el componente del fragmento. |
Caracteres |
Los URI de redireccionamiento no pueden contener ciertos caracteres, entre los que se incluyen los siguientes:
|
Autorización incremental
En el protocolo OAuth 2.0, tu app solicita autorización para acceder a los recursos, los cuales se identificados por permisos. Solicitar autorización se considera una práctica recomendada de la experiencia del usuario. los recursos en el momento en que los necesites. Para habilitar esta práctica, el servidor de autorización de Google admite la autorización incremental. Esta función te permite solicitar permisos a medida que los necesites si el usuario otorga permiso para el nuevo alcance, devuelve un código de autorización por un token que contiene todos los permisos que el usuario le otorgó al proyecto.
Por ejemplo, supongamos que una aplicación obtiene datos para el canal de YouTube del usuario autenticado y también
permite que un usuario recupere datos de YouTube Analytics a través de un flujo especial. En este caso, al ingresar
momento, la app podría solicitar acceso solo al https://www.googleapis.com/auth/youtube.force-ssl
del proyecto. Sin embargo, si el usuario intenta acceder a los datos de Analytics de su canal, la app también podría
solicitar acceso al permiso https://www.googleapis.com/auth/yt-analytics.readonly
Para implementar la autorización incremental, completa el flujo normal de solicitud de acceso token, pero asegúrate de que la solicitud de autorización incluya alcances otorgados anteriormente. Esta permite que tu app evite tener que administrar múltiples tokens de acceso.
Las siguientes reglas se aplican a un token de acceso obtenido de una autorización incremental:
- El token se puede usar para acceder a los recursos correspondientes a cualquiera de los permisos incluidos en el nueva autorización combinada.
- Cuando usa el token de actualización para la autorización combinada a fin de obtener un token de acceso, el
el token de acceso representa la autorización combinada y puede usarse para cualquiera de los
Valores
scope
incluidos en la respuesta. - La autorización combinada incluye todos los alcances que el usuario otorgó al proyecto de API, incluso si se solicitaron subsidios a diferentes clientes. Por ejemplo, si un usuario al que se le otorga acceso un alcance con un cliente de escritorio de una aplicación y, luego, se otorga otro alcance al mismo aplicación mediante un cliente móvil, la autorización combinada incluiría ambos alcances.
- Si revoca un token que representa una autorización combinada, podrá acceder a todo ese token se revocan simultáneamente los permisos de la autorización en nombre del usuario asociado.
Las muestras de código específicas del lenguaje incluidas en el Paso 1: Configura la autorización parámetros y la URL de redireccionamiento HTTP/REST de muestra en el Paso 2: Para redireccionar al servidor OAuth 2.0 de Google, todos usan autorización incremental. Las muestras de código a continuación también muestran el código que debes agregar para usar la autorización incremental.
PHP
$client->setIncludeGrantedScopes(true);
Python
En Python, establece el argumento de palabra clave include_granted_scopes
en true
, de la siguiente manera:
asegurarse de que la solicitud de autorización incluya permisos otorgados previamente. Es muy posible que
include_granted_scopes
no será el único argumento de palabra clave que establecerás, ya que
que se muestra en el siguiente ejemplo.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Rita
auth_client.update!( :additional_parameters => {"include_granted_scopes" => "true"} )
Node.js
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
HTTP o REST
En este ejemplo, la aplicación que realiza la llamada solicita acceso para recuperar el datos de YouTube del usuario, además de cualquier otro acceso al que el usuario ya otorgaste a la aplicación.
GET https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl& access_type=offline& state=security_token%3D138rk%3Btarget_url%3Dhttp...index& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& response_type=code& client_id=client_id& include_granted_scopes=true
Refreshing an access token (offline access)
Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.
- If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
- If you are not using a client library, you need to set the
access_type
HTTP query parameter tooffline
when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.
Requesting offline access is a requirement for any application that needs to access a Google
API when the user is not present. For example, an app that performs backup services or
executes actions at predetermined times needs to be able to refresh its access token when the
user is not present. The default style of access is called online
.
Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.
PHP
If your application needs offline access to a Google API, set the API client's access type to
offline
:
$client->setAccessType("offline");
Después de que el usuario otorgue acceso sin conexión a los permisos solicitados, puedes seguir usando la API cliente acceda a las APIs de Google en nombre del usuario cuando este no tenga conexión. El objeto cliente actualizará el token de acceso según sea necesario.
Python
En Python, establece el argumento de palabra clave access_type
en offline
para asegurarte de que
que podrás actualizar el token de acceso sin tener que volver a solicitar al usuario
permiso. Es muy posible que access_type
no sea la única palabra clave.
que establezcas, como se muestra en el siguiente ejemplo.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Después de que el usuario otorgue acceso sin conexión a los permisos solicitados, puedes seguir usando la API cliente acceda a las APIs de Google en nombre del usuario cuando este no tenga conexión. El objeto cliente actualizará el token de acceso según sea necesario.
Rita
Si tu aplicación necesita acceso sin conexión a una API de Google, establece el tipo de acceso del cliente de la API en
offline
auth_client.update!( :additional_parameters => {"access_type" => "offline"} )
Después de que el usuario otorgue acceso sin conexión a los permisos solicitados, puedes seguir usando la API cliente acceda a las APIs de Google en nombre del usuario cuando este no tenga conexión. El objeto cliente actualizará el token de acceso según sea necesario.
Node.js
Si tu aplicación necesita acceso sin conexión a una API de Google, establece el tipo de acceso del cliente de la API en
offline
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
Después de que el usuario otorgue acceso sin conexión a los permisos solicitados, puedes seguir usando la API cliente acceda a las APIs de Google en nombre del usuario cuando este no tenga conexión. El objeto cliente actualizará el token de acceso según sea necesario.
Los tokens de acceso vencen. Esta biblioteca usará automáticamente un token de actualización para obtener un acceso nuevo token correcto si está a punto de vencer. Una forma sencilla de asegurarte de almacenar siempre los tokens más recientes es usar el evento de tokens:
oauth2Client.on('tokens', (tokens) => { if (tokens.refresh_token) { // store the refresh_token in your secure persistent database console.log(tokens.refresh_token); } console.log(tokens.access_token); });
Este evento de token solo ocurre en la primera autorización y debes haber establecido tu
access_type
a offline
cuando se llama a generateAuthUrl
para recibir el token de actualización. Si ya le otorgaste a tu app los permisos necesarios
sin establecer las restricciones adecuadas para recibir un token de actualización, deberás
volver a autorizar la aplicación para que reciba un token de actualización nuevo.
Para configurar refresh_token
más adelante, puedes usar el método setCredentials
:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
Una vez que el cliente tenga un token de actualización, los tokens de acceso se adquirirán y actualizarán automáticamente en la próxima llamada a la API.
HTTP o REST
Para actualizar un token de acceso, tu aplicación envía un POST
HTTPS
solicitud al servidor de autorización de Google (https://oauth2.googleapis.com/token
) que
incluye los siguientes parámetros:
Campos | |
---|---|
client_id |
El ID de cliente obtenido de API Console. |
client_secret |
El secreto del cliente obtenido de API Console. |
grant_type |
Como
definidas en el
especificación de OAuth 2.0,
el valor de este campo debe establecerse en refresh_token . |
refresh_token |
El token de actualización que muestra el intercambio del código de autorización. |
En el siguiente fragmento, se muestra una solicitud de muestra:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
Siempre que el usuario no haya revocado el acceso otorgado a la aplicación, el servidor de tokens devuelve un objeto JSON que contiene un token de acceso nuevo. En el siguiente fragmento, se muestra un ejemplo respuesta:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "token_type": "Bearer" }
Ten en cuenta que existen límites en la cantidad de tokens de actualización que se emitirán. un límite por una combinación de cliente y usuario y otra por usuario en todos los clientes. Debes guardar los tokens de actualización. en un almacenamiento a largo plazo y seguir usándolos mientras sean válidos. Si tu aplicación solicita demasiados tokens de actualización, se pueden alcanzar estos límites, en cuyo caso los tokens de actualización más antiguos dejará de funcionar.
Revoca un token
En algunos casos, es posible que el usuario desee revocar el acceso otorgado a una aplicación. Un usuario puede revocar el acceso en Configuración de la cuenta. Consulta la Quitar Acceso al sitio o la aplicación de la sección de Sitios de terceros y apps con acceso a tu cuenta para obtener más información.
También es posible que una aplicación revoque de forma programática el acceso que se le otorgó. La revocación programática es importante en los casos en que un usuario anula la suscripción, quita aplicación o los recursos de API necesarios para una aplicación han cambiado considerablemente. En otras palabras, parte del proceso de eliminación pueden incluir una solicitud a la API para garantizar que los permisos previos otorgadas a la aplicación.
PHP
Para revocar un token de manera programática, llama a revokeToken()
:
$client->revokeToken();
Python
Para revocar un token de manera programática, haz una solicitud a
https://oauth2.googleapis.com/revoke
, que incluye el token como parámetro y establece la
Encabezado Content-Type
:
requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'})
Rita
Para revocar un token de manera programática, realiza una solicitud HTTP al oauth2.revoke
extremo:
uri = URI('https://oauth2.googleapis.com/revoke') response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
El token puede ser de acceso o de actualización. Si el token es de acceso y tiene un token de actualización correspondiente, también se revocará el token de actualización.
Si la revocación se procesa correctamente, el código de estado de la respuesta es
200
Para las condiciones de error, se devuelve un código de estado 400
junto con un
código de error.
Node.js
Para revocar un token de manera programática, realiza una solicitud HTTPS POST a /revoke
extremo:
const https = require('https'); // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end();
El parámetro del token puede ser un token de acceso o un token de actualización. Si el token es de acceso y tiene un token de actualización correspondiente, también se revocará el token de actualización.
Si la revocación se procesa correctamente, el código de estado de la respuesta es
200
Para las condiciones de error, se devuelve un código de estado 400
junto con un
código de error.
HTTP o REST
Para revocar un token de manera programática, la aplicación realiza una solicitud a
https://oauth2.googleapis.com/revoke
e incluye el token como parámetro:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
El token puede ser de acceso o de actualización. Si el token es de acceso y tiene un token de actualización correspondiente, también se revocará el token de actualización.
Si la revocación se procesa correctamente, el código de estado HTTP de la respuesta es
200
Para las condiciones de error, se muestra el código de estado HTTP 400
junto
con un código de error.
Cómo implementar la Protección integral de la cuenta
Un paso adicional que debes seguir para proteger las contraseñas de cuentas está implementando Protección con el Servicio de protección integral de la cuenta de Google Este servicio te permite suscribirse a las notificaciones de eventos de seguridad, que proporcionan información a su aplicación sobre cambios importantes en la cuenta de usuario. Luego, puedes usar la información para tomar medidas según cómo decides responder a los eventos.
Estos son algunos ejemplos de los tipos de eventos que el Servicio de Protección integral de la cuenta de Google envía a tu app:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
Consulta la Cómo proteger las cuentas de usuario con la página Protección integral de la cuenta para obtener más información sobre cómo implementar la Protección integral de la cuenta y consultar la lista completa de eventos disponibles.