Autentica desarrolladores, funciones y usuarios finales

Según la configuración predeterminada, solo los propietarios y los editores del proyecto pueden crear, actualizar o borrar funciones. A fin de otorgar a otros usuarios o grupos la capacidad de realizar estas acciones, puedes usar Cloud Identity and Access Management (IAM) y asignar funciones a diferentes miembros.

De manera similar, puedes usar el enfoque descrito anteriormente para asignar o restringir la capacidad de invocar una función. Este comportamiento difiere para las funciones de HTTP y las funciones en segundo plano:

  • Según la configuración predeterminada, cualquier usuario o servicio puede invocar una función de HTTP. Puedes configurar IAM en funciones de HTTP para restringir este comportamiento de modo que tu función de HTTP solo pueda invocarse con credenciales de autenticación en la solicitud.
  • Solo la fuente del evento al que están suscritas las funciones en segundo plano puede invocarlas.

A continuación, se presentan tres casos prácticos comunes de autenticación:

  • Asegura el acceso del desarrollador para que solo usuarios específicos puedan invocar la función durante la prueba.

  • Asegura el acceso de función a función para que solo las funciones autorizadas puedan invocar tu función.

  • Asegura el acceso del usuario final a una aplicación desde clientes móviles o web.

Desarrolladores

Además de las acciones administrativas, como crear, actualizar y borrar funciones, a menudo, los desarrolladores quieren probar funciones de forma privada antes de lanzarlas de forma pública.

Cuando usas curl o herramientas similares, debes tratarlas como solicitudes de usuario final y proporcionar un token de Google OAuth en el encabezado Authorization de la solicitud. Por ejemplo, puedes obtener un token por medio de gcloud de la siguiente manera:

curl https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME \
  -H "Authorization: bearer $(gcloud auth print-identity-token)"

Para que esta solicitud funcione, la función asignada al desarrollador debe contener el permiso cloudfunctions.functions.invoke. Según la configuración predeterminada, las funciones de Administrador y de Desarrollador de Cloud Functions tienen este permiso. Consulta Funciones de IAM de Cloud Functions para ver la lista completa de las funciones y los permisos asociados con estas.

Por último, te recomendamos otorgar el conjunto de permisos necesarios mínimos para el desarrollo y el uso de tus funciones. Asegúrate de que las políticas de IAM en tus funciones estén limitadas a la cantidad mínima de usuarios y cuentas de servicio.

Función a función

Cuando compilas servicios que conectan varias funciones, es recomendable que te asegures de que cada función solo pueda hacer solicitudes a ciertas funciones. Por ejemplo, si tienes una función login, esta debería poder acceder a la función user profiles, pero probablemente no debería poder acceder a la función search.

Primero, será necesario que configures la función receptora de modo que acepte solicitudes de la función que llama. Para ello, sigue estos pasos:

  1. Otorga la función de Invocador de Cloud Functions (roles/cloudfunctions.invoker) a la identidad de función que llama en la función receptora. Según la configuración predeterminada, esa identidad es PROJECT_ID@appspot.gserviceaccount.com.

Console

  1. Ve a Google Cloud Platform Console:

    Ir a Google Cloud Platform Console

  2. Haz clic en la casilla de verificación que se encuentra junto a la función cuyos permisos deseas modificar.

  3. Haz clic en Mostrar panel de información en la esquina superior derecha para que aparezca la pestaña Permisos, que muestra los permisos asignados a la función.

  4. En el campo Agregar miembros, ingresa la identidad del entorno de ejecución de la función que llama. Debería ser el correo electrónico de una cuenta de servicio.

  5. Selecciona la función Cloud Functions Invoker en el menú desplegable Selecciona una función.

  6. Haz clic en Agregar.

gcloud

Usa el comando gcloud beta functions add-iam-policy-binding:

gcloud beta functions add-iam-policy-binding RECEIVING_FUNCTION \
  --member='serviceAccount:CALLING_FUNCTION_IDENTITY' \
  --role='roles/cloudfunctions.invoker'

donde RECEIVING_FUNCTION es la función receptora y CALLING_FUNCTION_IDENTITY es la identidad de la función que llama.

En la función que llama, será necesario que hagas lo siguiente:

  1. Crea un token de ID de OAuth firmado por Google con el público (aud) configurado en la URL de la función receptora.

  2. Incluye el token de ID en un encabezado Authorization: Bearer ID_TOKEN en la solicitud a la función.

Node.js
// Make sure to `npm install --save request-promise` or add the dependency to your package.json
const request = require('request-promise');

exports.callingFunction = (req, res) => {
  // Make sure to replace variables with appropriate values
  const receivingFunctionURL = 'https://REGION-PROJECT.cloudfunctions.net/RECEIVING_FUNCTION';

  // Set up metadata server request
  // See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
  const metadataServerTokenURL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
  const tokenRequestOptions = {
      uri: metadataServerTokenURL + receivingFunctionURL,
      headers: {
          'Metadata-Flavor': 'Google'
      }
  };

  // Fetch the token, then provide the token in the request to the receiving function
  request(tokenRequestOptions)
    .then((token) => {
      return request(receivingFunctionURL).auth(null, null, true, token)
    })
    .then((response) => {
      res.status(200).send(response);
    })
    .catch((error) => {
      res.status(400).send(error);
    });
};
    
Python
# Requests is already installed, no need to add it to requirements.txt
import requests

def calling_function(request):
  # Make sure to replace variables with appropriate values
  receiving_function_url = 'https://REGION-PROJECT.cloudfunctions.net/RECEIVING_FUNCTION'

  # Set up metadata server request
  # See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
  metadata_server_token_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='

  token_request_url = metadata_server_token_url + receiving_function_url
  token_request_headers = {'Metadata-Flavor': 'Google'}

  # Fetch the token
  token_response = requests.get(token_request_url, headers=token_request_headers)
  jwt = token_response.content.decode("utf-8")

  # Provide the token in the request to the receiving function
  receiving_function_headers = {'Authorization': f'bearer {jwt}'}
  function_response = requests.get(receiving_function_url, headers=receiving_function_headers)

  return function_response.content
    

Servicio a función

Si invocas una función desde una instancia de procesamiento que no tiene acceso a los metadatos de procesamiento (p. ej., tu propio servidor), tendrás que generar manualmente el token correspondiente con estos pasos:

  1. Autofirma un JWT de cuenta de servicio con la reclamación target_audience configurada en la URL de la función receptora.

  2. Intercambia el JWT autofirmado por un token de ID firmado por Google, que debería tener la reclamación aud configurada en la URL anterior.

  3. Incluye el token de ID en un encabezado Authorization: Bearer ID_TOKEN en la solicitud a la función.

Los documentos de Cloud IAP tienen un código de muestra para demostrar esta funcionalidad.

Usuarios finales

La mayoría de las aplicaciones administran solicitudes de usuarios finales, y se recomienda restringir el acceso a los usuarios finales con permiso únicamente. Con el fin de lograr lo anterior, puedes integrar el Acceso con Google y otorgarles a los usuarios la función de IAM roles/cloudfunctions.invoker o implementar Firebase Authentication y validar sus credenciales manualmente.

Acceso con Google

Primero, será necesario habilitar el Acceso con Google en tu proyecto de la siguiente manera:

  1. Crea un ID de cliente de OAuth 2.0 para tu aplicación en el mismo proyecto que la función que quieres proteger:
    1. Ve a la página Credenciales.

      Ir a la página Credenciales

    2. Selecciona el proyecto con la función que quieres asegurar.
    3. Haz clic en Crear credenciales y, luego, selecciona ID de cliente de OAuth.
      1. Es posible que se te pida configurar tu propia pantalla de consentimiento para OAuth antes de crear un ID de cliente. Si es necesario, hazlo para continuar.
    4. Selecciona el Tipo de aplicación para la que quieres crear credenciales.
    5. Agrega un Nombre y Restricciones si corresponde y, luego, haz clic en Crear.
  2. Vuelve a implementar la función que quieres proteger. Esto garantizará que se configure el ID de cliente correcto en la función.

Si tienes varios ID de cliente de OAuth (por ejemplo, uno por cada plataforma: Android, iOS y la Web), debes volver a implementar tus funciones después de agregar cada una para asegurarte de que la función capte el cambio. De forma similar, si borras un ID de cliente, debes volver a implementar tus funciones para quitarlo y rechazar sus solicitudes. Se aceptarán todos los ID de cliente dentro de un proyecto.

En tu aplicación web o para dispositivos móviles, será necesario que hagas lo siguiente:

  1. Obtén un token de ID para el ID de cliente de OAuth:
  2. Incluye el token de ID en un encabezado de Authorization: Bearer ID_TOKEN en la solicitud de la función.

Cloud Functions validará el token de auth y permitirá la solicitud, o la rechazará antes de que la función se inicie. Si se rechaza una solicitud, no se te cobrará por eso.

Obtén información del perfil del usuario

Si quieres acceder a la información del perfil del usuario, puedes extraer el token del encabezado Authorization, decodificar el token web JSON y extraer el cuerpo.

El cuerpo del token de ID debe contener la siguiente información:

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile"
 // and "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

No es necesario validar el token, dado que Cloud IAM ya lo hizo.

Soluciona problemas

Si se rechazan las solicitudes de los usuarios y consideras que deben aceptarse, asegúrate de que a los usuarios se les haya otorgado la función roles/cloudfunctions.invoker o de que tengan el permiso cloudfunctions.functions.invoke. Obtén más información sobre lo anterior en la referencia de IAM de Cloud Functions.

Apps web, autenticación y CORS

Si quieres compilar una aplicación web que esté protegida con la IAM de Cloud Functions y el Acceso con Google, es probable que debas trabajar con el uso compartido de recursos multiorigen (CORS). Las solicitudes de comprobación previa de CORS se envían sin un encabezado de Authorization, por lo que se rechazarán en todas las funciones de HTTP no públicas. Como las solicitudes de comprobación previa fallan, la solicitud principal también lo hará.

Para sortear lo anterior, puedes alojar tu aplicación web y las funciones en el mismo dominio a fin de evitar las solicitudes de comprobación previa de CORS. De lo contrario, debes hacer públicas tus funciones, además de administrar CORS y la autenticación en el código de la función.

También puedes implementar un proxy de Cloud Endpoints y habilitar CORS. Si deseas contar con capacidades de autenticación, también puedes habilitar la validación del token de ID de Google, que validará estos mismos tokens de autenticación.

Firebase Authentication

Si quieres autenticar usuarios con correo electrónico/contraseña, número de teléfono, proveedores de redes sociales como Facebook o GitHub, o con un mecanismo de autenticación personalizado, puedes usar Firebase Authentication.

Primero, deberás configurar Firebase Authentication en tu proyecto y función con estos pasos:

  1. Configura Firebase Authentication en Firebase Console.

    Ir a Firebase Console

  2. Importa el SDK de Firebase Admin correspondiente y configúralo correctamente.

  3. Agrega middleware a tu código para verificar los tokens de ID de Firebase.

  4. Implementa tu función públicamente.

En tu aplicación web o para dispositivos móviles, es necesario que hagas lo siguiente:

  1. Usa la biblioteca cliente de Firebase Auth para obtener un token de ID:
  2. Incluye el token de ID en un encabezado Authorization: Bearer ID_TOKEN en la solicitud a la función.

También puedes implementar un proxy de Cloud Endpoints y habilitar la validación del token de ID de Firebase, que validará estos mismos tokens de autenticación.

Obtén información del perfil del usuario

Si quieres acceder a la información del perfil del usuario, puedes usar el SDK de Firebase Admin para recuperar los datos del usuario.

Claves de API

Las claves de API identifican la aplicación cliente y el proyecto de GCP que llaman a tu API, lo que te permite realizar una autorización simple, así como verificaciones de cuotas y límites de frecuencia.

Las claves de API no son tan seguras como los otros métodos de autenticación que se enumeran aquí por los siguientes motivos:

  1. Las claves de API son de larga duración. Esto significa que, aunque se filtren, se pueden usar indefinidamente (o al menos hasta que se roten las claves, lo que requiere que todos los clientes actualicen la clave).
  2. Las claves de API suelen almacenarse del lado del cliente, lo que las hace vulnerables a ser reutilizadas por terceros malintencionados.

Si eliges utilizar claves de API para el límite de frecuencia y cuotas, te recomendamos que las uses junto con tokens de autenticación.

A fin de configurar el acceso a las claves de API, implementa un proxy de Cloud Endpoints y configura tu securityDefinitions para habilitar la validación de las claves de API.

Próximos pasos

Aprende cómo administrar el acceso a las funciones que se están autenticando.

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Documentación de Cloud Functions