OAuth 2.0 y autorización JWT en Go: guía práctica

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

OAuth 2.0 y autorización JWT en Go: de la teoría a la práctica

\n\n

Las aplicaciones web y API modernas rara vez prescinden de un sistema robusto de autenticación y autorización. Dos estándares — OAuth 2.0 y JWT (JSON Web Tokens) — se han convertido en estándares de facto en el mundo del desarrollo. En este artículo, analizaremos con ejemplos prácticos cómo implementar la autorización OAuth 2.0 utilizando JWT en el lenguaje Go (Golang).

\n\n

Crearemos un servidor REST API simple que emitirá tokens JWT después de una autenticación exitosa a través de un proveedor OAuth 2.0 (por ejemplo, Google) y los verificará en cada solicitud.

\n\n

1. Fundamentos de OAuth 2.0 y JWT

\n\n

Antes de escribir código, aclaremos brevemente los términos.

\n\n
    \n
  • OAuth 2.0 — es un protocolo de autorización que permite a los usuarios otorgar a terceros acceso limitado a sus recursos sin compartir su nombre de usuario y contraseña. Roles principales: Resource Owner (usuario), Client (nuestra aplicación), Authorization Server (servidor que emite tokens), Resource Server (servidor con datos protegidos).
  • \n
  • JWT — es un formato de token compacto y seguro para URL que consta de tres partes: header, payload y signature. JWT puede contener cualquier dato (claims) y se firma con una clave secreta o un par de claves RSA.
  • \n
\n\n

En nuestra implementación, OAuth 2.0 se utilizará para obtener un token de identidad del proveedor (Google), y luego generaremos nuestro propio JWT para el trabajo posterior con nuestra API.

\n\n

2. Configuración del proyecto y dependencias

\n\n

Creemos un nuevo proyecto en Go e instalemos los paquetes necesarios:

\n\n
mkdir go-oauth-jwt\ncd go-oauth-jwt\ngo mod init example.com/go-oauth-jwt\ngo get github.com/gin-gonic/gin\ngo get github.com/golang-jwt/jwt/v5\ngo get golang.org/x/oauth2\ngo get golang.org/x/oauth2/google
\n\n

Usaremos:

\n
    \n
  • Gin — un framework HTTP rápido para Go.
  • \n
  • golang-jwt — una biblioteca para trabajar con JWT.
  • \n
  • oauth2 — la biblioteca estándar de Go para OAuth 2.0.
  • \n
\n\n

También necesitarás registrar una aplicación en Google Cloud Console, crear un OAuth 2.0 Client ID y Secret, y especificar la Redirect URI (por ejemplo, http://localhost:8080/auth/google/callback).

\n\n

3. Implementación del inicio de sesión OAuth 2.0 a través de Google

\n\n

Comencemos creando la configuración de OAuth 2.0 y los endpoints para el inicio de sesión y la devolución de llamada.

\n\n
package main\n\nimport (\n    "crypto/rand"\n    "encoding/base64"\n    "net/http"\n    "os"\n\n    "github.com/gin-gonic/gin"\n    "golang.org/x/oauth2"\n    "golang.org/x/oauth2/google"\n)\n\nvar (\n    googleOauthConfig *oauth2.Config\n    oauthStateString  string\n)\n\nfunc init() {\n    googleOauthConfig = &oauth2.Config{\n        RedirectURL:  "http://localhost:8080/auth/google/callback",\n        ClientID:     os.Getenv("GOOGLE_CLIENT_ID"),\n        ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),\n        Scopes:       []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"},\n        Endpoint:     google.Endpoint,\n    }\n    // Generamos un token state aleatorio para protección contra CSRF\n    b := make([]byte, 32)\n    rand.Read(b)\n    oauthStateString = base64.StdEncoding.EncodeToString(b)\n}\n\nfunc main() {\n    r := gin.Default()\n\n    r.GET("/auth/google/login", handleGoogleLogin)\n    r.GET("/auth/google/callback", handleGoogleCallback)\n\n    r.Run(":8080")\n}\n\nfunc handleGoogleLogin(c *gin.Context) {\n    url := googleOauthConfig.AuthCodeURL(oauthStateString)\n    c.Redirect(http.StatusTemporaryRedirect, url)\n}\n\nfunc handleGoogleCallback(c *gin.Context) {\n    state := c.Query("state")\n    if state != oauthStateString {\n        c.JSON(http.StatusBadRequest, gin.H{"error": "invalid oauth state"})\n        return\n    }\n\n    code := c.Query("code")\n    token, err := googl                

Blogs

Book Recommendations