OAuth 2.0 y autorización JWT en Swift: guía paso a paso 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

Introducción a OAuth 2.0 y JWT en Swift

\n\n

Las aplicaciones móviles y de escritorio modernas rara vez prescinden de la autenticación. Dos protocolos clave — OAuth 2.0 y JWT (JSON Web Token) — se han convertido en el estándar de facto para la transferencia segura de datos entre el cliente y el servidor. En este artículo, analizaremos cómo implementar la autorización OAuth 2.0 y JWT en Swift para las plataformas iOS y macOS. Aprenderá cómo configurar el flujo de obtención de tokens, almacenarlos en Keychain y renovarlos automáticamente cuando caduquen.

\n\n

El artículo está dirigido a desarrolladores principiantes que ya están familiarizados con los fundamentos de Swift y SwiftUI. Usaremos URLSession para las solicitudes de red y Keychain para el almacenamiento seguro de datos. El código está escrito en Swift 5.9 y es compatible con iOS 15+ / macOS 12+.

\n\n

¿Qué son OAuth 2.0 y JWT?

\n\n

Antes de escribir código, analicemos la teoría.

\n\n

OAuth 2.0

\n

OAuth 2.0 es un protocolo de autorización que permite a una aplicación obtener acceso limitado a los recursos de un usuario sin transferir su nombre de usuario y contraseña. En su lugar, se utilizan tokens de acceso. Los participantes principales son:

\n
    \n
  • Resource Owner — el usuario.
  • \n
  • Client — su aplicación.
  • \n
  • Authorization Server — el servidor que emite los tokens.
  • \n
  • Resource Server — la API que proporciona los datos.
  • \n
\n\n

El flujo más popular para aplicaciones móviles es Authorization Code Flow with PKCE (Proof Key for Code Exchange). Es seguro incluso sin un client secret, que es difícil de almacenar en la aplicación.

\n\n

JWT (JSON Web Token)

\n

JWT es un formato de token compacto y autónomo que contiene datos JSON. Consta de tres partes separadas por puntos:

\n
    \n
  • Header — el tipo de token y el algoritmo de firma.
  • \n
  • Payload — los datos útiles (claims), como el id del usuario, el rol, la fecha de caducidad.
  • \n
  • Signature — la firma para verificar la integridad.
  • \n
\n\n

JWT se utiliza a menudo como access token en OAuth 2.0. Permite al servidor verificar la autenticidad de la solicitud sin consultar la base de datos.

\n\n

Implementación práctica en Swift

\n\n

Crearemos una clase simple AuthService que gestionará la autenticación. Para el ejemplo, usaremos el servidor https://api.example.com.

\n\n

Paso 1: Obtención de tokens mediante OAuth 2.0

\n\n

Primero, implementaremos un método para obtener tokens mediante un código de autorización. Supongamos que ya hemos obtenido el authorizationCode a través de una vista web (por ejemplo, ASWebAuthenticationSession).

\n\n
import Foundation\n\nfinal class AuthService {\n    static let shared = AuthService()\n    private let baseURL = "https://api.example.com"\n    private let clientID = "your_client_id"\n    private let redirectURI = "yourapp://callback"\n    \n    // MARK: - Obtención de tokens\n    func exchangeCodeForTokens(code: String, codeVerifier: String) async throws -> TokenResponse {\n        let url = URL(string: "\\(baseURL)/oauth/token")!\n        var request = URLRequest(url: url)\n        request.httpMethod = "POST"\n        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")\n        \n        let body = [\n            "grant_type": "authorization_code",\n            "code": code,\n            "redirect_uri": redirectURI,\n            "client_id": clientID,\n            "code_verifier": codeVerifier\n        ]\n        .map { "\\($0.key)=\\($0.value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")" }\n        .joined(separator: "&")\n        .data(using: .utf8)\n        \n        request.httpBody = body\n        \n        let (data, response) = try await URLSession.shared.data(for: request)\n        \n        guard let httpResponse = response as? HTTPURLResponse,                

Blogs

Book Recommendations