En este módulo, aprenderemos cómo implementar autenticación y autorización en un servidor GraphQL. Estos conceptos son fundamentales para asegurar que solo los usuarios autorizados puedan acceder a ciertos datos y realizar ciertas acciones en tu aplicación.
Conceptos Clave
Autenticación
La autenticación es el proceso de verificar la identidad de un usuario. En otras palabras, es cómo sabemos quién es el usuario. Esto generalmente se realiza mediante el uso de credenciales como nombres de usuario y contraseñas, tokens de acceso, etc.
Autorización
La autorización es el proceso de verificar si un usuario autenticado tiene permiso para realizar una acción específica o acceder a ciertos datos. Esto se basa en roles y permisos asignados al usuario.
Implementación de Autenticación y Autorización en GraphQL
- Configuración del Servidor
Primero, necesitamos configurar nuestro servidor GraphQL para manejar la autenticación. En este ejemplo, usaremos JSON Web Tokens (JWT) para la autenticación.
Instalación de Dependencias
Configuración del Middleware de Autenticación
const express = require('express'); const { ApolloServer, gql } = require('apollo-server-express'); const jwt = require('express-jwt'); const jsonwebtoken = require('jsonwebtoken'); const app = express(); const authMiddleware = jwt({ secret: 'your_secret_key', credentialsRequired: false, algorithms: ['HS256'], }); app.use(authMiddleware);
- Definición del Esquema
Definimos nuestro esquema GraphQL con un tipo User
y una consulta me
que devuelve la información del usuario autenticado.
const typeDefs = gql` type User { id: ID! username: String! email: String! } type Query { me: User } `;
- Implementación de Resolvers
Implementamos los resolvers para manejar la lógica de negocio. En este caso, el resolver me
devolverá la información del usuario autenticado.
const resolvers = { Query: { me: (parent, args, context) => { if (!context.user) { throw new Error('Not authenticated'); } return context.user; }, }, };
- Configuración del Contexto
Configuramos el contexto de Apollo Server para incluir la información del usuario autenticado.
const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { const user = req.user || null; return { user }; }, }); server.applyMiddleware({ app }); app.listen({ port: 4000 }, () => console.log(`Server ready at http://localhost:4000${server.graphqlPath}`) );
- Autorización Basada en Roles
Para implementar la autorización, podemos definir roles y permisos y verificar estos roles en nuestros resolvers.
Definición de Roles
Verificación de Roles en Resolvers
const resolvers = { Query: { me: (parent, args, context) => { if (!context.user) { throw new Error('Not authenticated'); } return context.user; }, adminData: (parent, args, context) => { if (!context.user || context.user.role !== roles.ADMIN) { throw new Error('Not authorized'); } return { secretData: 'This is admin data' }; }, }, };
Ejercicio Práctico
Ejercicio 1: Implementar Autenticación
- Configura un servidor GraphQL con autenticación usando JWT.
- Define un esquema con un tipo
User
y una consultame
. - Implementa los resolvers para manejar la autenticación y devolver la información del usuario autenticado.
Ejercicio 2: Implementar Autorización
- Define roles y permisos en tu aplicación.
- Implementa la lógica de autorización en los resolvers para restringir el acceso a ciertas consultas y mutaciones basadas en los roles del usuario.
Solución del Ejercicio 1
// Paso 1: Configuración del servidor const express = require('express'); const { ApolloServer, gql } = require('apollo-server-express'); const jwt = require('express-jwt'); const jsonwebtoken = require('jsonwebtoken'); const app = express(); const authMiddleware = jwt({ secret: 'your_secret_key', credentialsRequired: false, algorithms: ['HS256'], }); app.use(authMiddleware); // Paso 2: Definición del esquema const typeDefs = gql` type User { id: ID! username: String! email: String! } type Query { me: User } `; // Paso 3: Implementación de resolvers const resolvers = { Query: { me: (parent, args, context) => { if (!context.user) { throw new Error('Not authenticated'); } return context.user; }, }, }; // Paso 4: Configuración del contexto const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { const user = req.user || null; return { user }; }, }); server.applyMiddleware({ app }); app.listen({ port: 4000 }, () => console.log(`Server ready at http://localhost:4000${server.graphqlPath}`) );
Solución del Ejercicio 2
// Paso 1: Definición de roles const roles = { ADMIN: 'ADMIN', USER: 'USER', }; // Paso 2: Verificación de roles en resolvers const resolvers = { Query: { me: (parent, args, context) => { if (!context.user) { throw new Error('Not authenticated'); } return context.user; }, adminData: (parent, args, context) => { if (!context.user || context.user.role !== roles.ADMIN) { throw new Error('Not authorized'); } return { secretData: 'This is admin data' }; }, }, };
Conclusión
En esta sección, hemos aprendido cómo implementar autenticación y autorización en un servidor GraphQL. La autenticación nos permite verificar la identidad de los usuarios, mientras que la autorización nos permite controlar el acceso a los recursos y acciones basados en roles y permisos. Estos conceptos son esenciales para construir aplicaciones seguras y robustas.
En el siguiente módulo, exploraremos cómo optimizar las consultas en GraphQL para mejorar el rendimiento de nuestras aplicaciones.
Curso de GraphQL
Módulo 1: Introducción a GraphQL
- ¿Qué es GraphQL?
- GraphQL vs REST
- Configuración de un Servidor GraphQL
- Conceptos Básicos del Esquema de GraphQL
Módulo 2: Conceptos Fundamentales
Módulo 3: Diseño Avanzado de Esquemas
Módulo 4: Trabajando con Datos
Módulo 5: Rendimiento y Seguridad
Módulo 6: Herramientas y Ecosistema
Módulo 7: Pruebas y Despliegue
- Pruebas Unitarias de Resolvers
- Pruebas de Integración
- Integración Continua
- Despliegue de Servidores GraphQL