Saltar al contenido principal

Añade autenticación a tu aplicación Hasura

Hasura es una herramienta que puede proporcionar rápidamente las API GraphQL y REST correspondientes a tus datos. Considerando la seguridad de los datos, Hasura también ofrece la capacidad de ajustar el control de acceso para cada API diferente.

Por lo general, los usuarios de Hasura utilizan otros servicios de gestión de identidad y autenticación, siendo Logto uno muy popular entre ellos.

En esta publicación del blog, asumiremos que ya estás utilizando los servicios de Hasura. Presentaremos cómo integrar Hasura y Logto para maximizar la seguridad de tus datos. Si no tienes una cuenta de Logto, ¡regístrate y comienza a usarla ahora!

Antecedentes

Hasura emplea gestión de acceso basada en roles, mientras que Logto utiliza el estándar Control de acceso basado en roles (RBAC).

En el modelo de Logto y las mejores prácticas para RBAC, aconsejamos a los usuarios usar scope para corresponder a la granularidad más fina de permisos, usar role como un conjunto de scopes para operaciones por lotes convenientes, y finalmente verificar scope (generalmente en el lado de los proveedores de recursos) para verificar si un usuario puede realizar una operación específica.

En Hasura, un role corresponde a la granularidad más fina de permisos, y las verificaciones de permisos se realizan contra roles. Por lo tanto, durante la configuración de Logto, recomendamos mapear un role a exactamente un scope. Este enfoque puede vincular los permisos de Logto y Hasura para evitar confusiones y mal uso.

Hasura puede admitir el control de acceso utilizando Webhooks o JWT. Nuestra publicación anterior del blog introdujo cómo usar Webhooks, y en las siguientes secciones, explicaremos cómo utilizar el control de acceso en modo JWT de Hasura.

Comenzar

Comencemos con un ejemplo simple. Supongamos que un usuario ya tiene dos API en Hasura, GET /user y PATCH /user, correspondientes a dos roles: user:reader y user:maintainer, respectivamente.

1. Crear recurso de API de Hasura en Logto

Crea un recurso de API de Hasura en Logto.

Hasura API

2. Crear roles según la configuración de Hasura en Logto

Necesitamos crear dos scopes para el recurso de API de Hasura mencionado en el paso 1, a saber, read:user y maintain:user, y luego crear dos roles: user:reader (que contiene el scope read:user) y user:maintainer (que incluye el scope maintain:user) para corresponder uno a uno con los roles de Hasura. Y asignar estos roles a los usuarios de Logto según sea necesario.

Hasura API con scopes Rol de lector de usuario Rol de mantenedor de usuario

3. Configurar la variable de entorno de Hasura HASURA_GRAPHQL_JWT_SECRET para habilitar el modo JWT

Al revisar las opciones de configuración de JWT de Hasura, necesitamos agregar y configurar la variable de entorno HASURA_GRAPHQL_JWT_SECRET antes de poder usar JWT para el control de acceso.

Hay muchas opciones diferentes que se pueden configurar, pero aquí presentamos el caso más simple: solo se necesita configurar el jwk_url. Este valor se puede obtener desde tu endpoint de configuración de OpenID de Logto (https://your.logto.domain/oidc/.well-known/openid-configuration).

Configuración de JWT de Hasura

4. Personalizar reclamos adicionales del token de acceso del usuario

Usando la función de reclamos personalizados de tokens de Logto, personaliza la lógica para agregar reclamos adicionales al token de acceso del usuario.

Script de token de acceso del usuario

Personaliza el método getCustomJwtClaims para agregar datos en el JWT de los que Hasura depende para implementar el control de acceso. Esto puede incluir datos relacionados con el usuario que está siendo autorizado durante esa instancia, incluidos los roles que poseen, que se pueden acceder a través de context.

También hemos definido una variable de entorno USER_DEFAULT_ROLE_NAMES para evitar codificación fija.

5. Integrar Logto SDK

Después de configurar Logto y Hasura, integra tu aplicación con el Logto SDK. Aquí usamos un ejemplo de React para previsualizar el token de acceso del usuario emitido por Logto después del inicio de sesión del usuario.

Usuario con roles

Primero, asignamos los roles user:reader y user:maintainer creados anteriormente al usuario, y luego iniciamos sesión como ese usuario.

const config: LogtoConfig = {
endpoint: 'http://localhost:3001',
appId: '<your-application-id>',
appSecret: '<your-application-secret>',
scopes: [
...// scopes existentes
'read:user',
'maintain:user',
],
resources: [
...// recursos existentes
'https://*.hasura.app/api',
],
};

Obtén el token de acceso del usuario y solicita las API de Hasura:

const accessToken = await logto.getAccessToken('https://*.hasura.app/api');

// Antes de enviar la solicitud a Hasura
request.headers.set('Authorization', `Bearer ${accessToken}`);
request.headers.set('x-Hasura-Role', '<required-role-for-the-endpoint>');

Conclusión

En este artículo, proporcionamos otro método de control de acceso basado en JWT compatible con Hasura, además de Webhook.

Al comparar los procesos de control de acceso de Webhook y JWT de Hasura, podemos ver que el enfoque de Webhook envía un Webhook a Logto y espera una respuesta con cada solicitud de Hasura; mientras que el enfoque basado en JWT se puede usar continuamente hasta que el JWT expire.

El enfoque de JWT puede reducir la carga de la red y eliminar la latencia de red provocada por los Webhooks; mientras tanto, el enfoque de Webhook puede sincronizar cambios en los permisos de usuario en tiempo real.

Los usuarios pueden elegir el enfoque apropiado basado en estas conclusiones, combinadas con sus necesidades comerciales reales.