Tokens JWT en Go (Golang): creación y verificación con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Tokens JWT en Go (Golang): guía completa

\n\n

JSON Web Tokens (JWT) es un estándar abierto (RFC 7519) para crear tokens de acceso basados en JSON. JWT se utiliza ampliamente para la autenticación y el intercambio de información entre el cliente y el servidor. En el lenguaje Go (Golang), trabajar con tokens JWT se implementa de manera simple y eficiente gracias a la biblioteca golang-jwt/jwt.

\n\n

En este artículo, analizaremos en detalle la creación, firma, verificación y uso de tokens JWT en Go. El material será útil tanto para principiantes como para desarrolladores experimentados que deseen implementar autenticación segura en sus proyectos en Golang.

\n\n

Instalación de la biblioteca golang-jwt

\n\n

Para trabajar con JWT en Go, se utiliza el paquete github.com/golang-jwt/jwt/v5. Instálelo con el comando:

\n\n
go get github.com/golang-jwt/jwt/v5
\n\n

Después de la instalación, puede importar el paquete en su código:

\n\n
import (\n    "github.com/golang-jwt/jwt/v5"\n)
\n\n

Estructura del token JWT

\n\n

Un token JWT consta de tres partes, separadas por puntos:

\n\n
    \n
  • Header (encabezado) — contiene el tipo de token (JWT) y el algoritmo de firma (por ejemplo, HS256 o RS256).
  • \n
  • Payload (carga útil) — contiene los datos (claims), como el identificador de usuario, rol, fecha de expiración, etc.
  • \n
  • Signature (firma) — se crea a partir del header y payload utilizando una clave secreta o un par de claves RSA/ECDSA.
  • \n
\n\n

Creación de un token JWT en Go

\n\n

Veamos un ejemplo de creación de un token JWT con el algoritmo HMAC-SHA256 (HS256). Para esto, se necesita una clave secreta.

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n    "github.com/golang-jwt/jwt/v5"\n)\n\nfunc main() {\n    // Clave secreta (debe almacenarse en un lugar seguro)\n    secretKey := []byte("my_secret_key_12345")\n\n    // Creamos los claims (afirmaciones)\n    claims := jwt.MapClaims{\n        "user_id": 123,\n        "role":    "admin",\n        "exp":     time.Now().Add(time.Hour * 24).Unix(), // token válido por 24 horas\n        "iat":     time.Now().Unix(),\n    }\n\n    // Creamos el token\n    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\n    // Firmamos el token con la clave secreta\n    tokenString, err := token.SignedString(secretKey)\n    if err != nil {\n        fmt.Println("Error al crear el token:", err)\n        return\n    }\n\n    fmt.Println("Token JWT creado:")\n    fmt.Println(tokenString)\n}
\n\n

Verificación y análisis de un token JWT

\n\n

Para verificar la autenticidad del token, se utiliza la misma clave secreta. Es importante verificar la fecha de expiración y la firma.

\n\n
package main\n\nimport (\n    "fmt"\n    "github.com/golang-jwt/jwt/v5"\n)\n\nfunc main() {\n    tokenString := "su_token_aqui"\n    secretKey := []byte("my_secret_key_12345")\n\n    // Analizamos y verificamos el token\n    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {\n        // Verificamos el algoritmo de firma\n        if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {\n            return nil, fmt.Errorf("método de firma inesperado: %v", token.Header["alg"])\n        }\n        return secretKey, nil\n    })\n\n    if err != nil {\n        fmt.Println("Error al verificar el token:", err)\n        return\n    }\n\n    // Extraemos los claims\n    if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {\n        fmt.Println("¡Token válido!")\n        fmt.Printf("User ID: %v\\n", claims["user_id"])\n        fmt.Printf("Role: %v\\n", claims["role"])\n    } else {\n        fmt.Println("Token no válido")\n    }\n}
\n\n

Uso de claims estructurados

\n\n

Para mayor comodidad, puede definir su propia estructura de claims que implemente la interfaz jwt.Claims:

\n\n
type CustomClaims struct {\n    UserID int    `json:"user_id"`\n    Role   string `json:"role"`\n    jwt.RegisteredCl                    

Recommendations