OAuth 2.0 y autorización JWT en Kotlin: guía completa para principiantes

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

¿Qué son OAuth 2.0 y JWT y por qué se necesitan en Kotlin?

\n\n

En el desarrollo web moderno, la seguridad de los datos y la gestión de acceso son tareas clave. Si está escribiendo una aplicación de servidor en Kotlin, tarde o temprano se enfrentará a la necesidad de proteger una API u organizar el inicio de sesión a través de servicios de terceros (Google, GitHub, VK). Para ello, existen dos estándares: OAuth 2.0 (protocolo de autorización) y JWT (JSON Web Token — formato de token).

\n\n

En este artículo, analizaremos cómo funcionan OAuth 2.0 y JWT, e implementaremos una autorización simple en Kotlin utilizando bibliotecas populares. El material está dirigido a principiantes, por lo que todos los términos complejos se explicarán en un lenguaje sencillo.

\n\n

Conceptos básicos: OAuth 2.0 y JWT

\n\n

¿Qué es OAuth 2.0?

\n

OAuth 2.0 es un protocolo que permite a un servicio (por ejemplo, su aplicación) obtener acceso limitado a los recursos de un usuario en otro servicio (por ejemplo, a su perfil de Google) sin transferir el nombre de usuario y la contraseña. Imagine que quiere iniciar sesión en un sitio web a través de su cuenta de Google — eso es OAuth 2.0.

\n\n

Participantes principales de OAuth 2.0:

\n
    \n
  • Resource Owner — el usuario, propietario de los datos.
  • \n
  • Client — su aplicación, que quiere obtener acceso.
  • \n
  • Authorization Server — el servidor que otorga el permiso (por ejemplo, Google).
  • \n
  • Resource Server — el servidor que almacena los datos del usuario (por ejemplo, la API de Google).
  • \n
\n\n

¿Qué es JWT?

\n

JWT es un formato de token compacto y autónomo que contiene información sobre el usuario (por ejemplo, ID, rol, fecha de caducidad). El token está firmado digitalmente, por lo que no se puede falsificar. JWT consta de tres partes separadas por puntos:

\n\n
header.payload.signature
\n\n

Ejemplo de un JWT decodificado:

\n
{\n  "sub": "1234567890",\n  "name": "Iván Petrov",\n  "iat": 1516239022,\n  "exp": 1516242622\n}
\n\n

La principal ventaja de JWT es que el servidor no necesita almacenar sesiones en la base de datos. Toda la información ya está dentro del token.

\n\n

Implementación de autorización JWT en Kotlin con Spring Boot

\n\n

Veamos un ejemplo práctico. Crearemos una API REST en Kotlin usando Spring Boot y Spring Security. Nuestra aplicación emitirá un token JWT tras una autenticación exitosa.

\n\n

Paso 1. Agregar dependencias

\n

Agregue las siguientes dependencias en build.gradle.kts:

\n\n
dependencies {\n    implementation("org.springframework.boot:spring-boot-starter-security")\n    implementation("org.springframework.boot:spring-boot-starter-web")\n    implementation("io.jsonwebtoken:jjwt-api:0.12.5")\n    runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.5")\n    runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.5")\n}
\n\n

Paso 2. Creación del servicio JWT

\n

Crearemos la clase JwtService, que generará y verificará los tokens:

\n\n
import io.jsonwebtoken.Claims\nimport io.jsonwebtoken.Jwts\nimport io.jsonwebtoken.security.Keys\nimport org.springframework.stereotype.Service\nimport java.util.*\n\n@Service\nclass JwtService {\n    private val secretKey = "mySecretKeyForJwtToken12345678901234567890" // mínimo 32 caracteres\n    private val expirationMs = 3600000L // 1 hora\n\n    fun generateToken(username: String): String {\n        val claims: Map = mapOf(\n            "sub" to username,\n            "iat" to Date(),\n            "exp" to Date(System.currentTimeMillis() + expirationMs)\n        )\n        return Jwts.builder()\n            .claims(claims)\n            .signWith(Keys.hmacShaKeyFor(secretKey.toByteArray()))\n            .compact()\n    }\n\n    fun extractUsername(token: String): String? {\n        return try {\n            val claims = parseToken(token)\n            claims.subject\n        } catch (e: Exception) {\n            nul                

Blogs

Book Recommendations