Introducción a OAuth 2.0 y JWT en Swift
\n\nLas 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\nEl 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\nAntes de escribir código, analicemos la teoría.
\n\nOAuth 2.0
\nOAuth 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
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\nJWT (JSON Web Token)
\nJWT 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
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\nImplementación práctica en Swift
\n\nCrearemos una clase simple AuthService que gestionará la autenticación. Para el ejemplo, usaremos el servidor https://api.example.com.
Paso 1: Obtención de tokens mediante OAuth 2.0
\n\nPrimero, 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).
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,