Cliente OAuth para Swift (iOS/macOS): guía completa

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

Librería de cliente OAuth para Swift (iOS/macOS)

\n\n

OAuth (Open Authorization) es un protocolo de autorización abierto que permite a las aplicaciones obtener acceso limitado a los recursos del usuario sin compartir su nombre de usuario y contraseña. En el ecosistema de Apple (iOS, macOS, watchOS, tvOS), la implementación de OAuth 2.0 es el estándar para la integración con servicios como Google, Facebook, GitHub, Twitter y muchos otros. Para los desarrolladores de Swift, existen varias librerías probadas que simplifican el proceso de autenticación y gestión de tokens.

\n\n

En este artículo, analizaremos una de las librerías más populares y flexibles: OAuthSwift, y también discutiremos una alternativa: AppAuth-iOS (recomendada por Google). Aprenderá cómo conectar la librería, realizar la autorización, obtener el access token, el refresh token y almacenarlos de forma segura.

\n\n

Características principales de OAuthSwift

\n\n
    \n
  • Soporte para OAuth 1.0 y OAuth 2.0
  • \n
  • Trabajo integrado con WebView (SFSafariViewController, WKWebView)
  • \n
  • Obtención y actualización automática del access token
  • \n
  • Soporte para varios tipos de concesión (Authorization Code, Implicit, Client Credentials, Resource Owner Password)
  • \n
  • Integración sencilla con Alamofire, URLSession y otros frameworks de red
  • \n
  • Callbacks asíncronos (completion handlers) y soporte para Combine (a través de extensiones)
  • \n
  • Almacenamiento seguro de tokens mediante Keychain
  • \n
\n\n

Instalación de OAuthSwift

\n\n

La librería se instala a través de Swift Package Manager (SPM) o CocoaPods. Ejemplo para SPM:

\n\n
// En Xcode: File → Add Packages...\n// URL: https://github.com/OAuthSwift/OAuthSwift.git\n// Versión: desde 2.2.0 en adelante
\n\n

O a través de Package.swift:

\n\n
dependencies: [\n    .package(url: "https://github.com/OAuthSwift/OAuthSwift.git", from: "2.2.0")\n]
\n\n

Ejemplo de integración con OAuth 2.0 (Google)

\n\n

Consideremos un escenario típico: autorización a través de Google para obtener un access token. Previamente, es necesario registrar la aplicación en Google Cloud Console y obtener el client_id y client_secret.

\n\n

Paso 1. Configuración del esquema URL

\n\n

En el archivo Info.plist, agregue el esquema para la devolución de llamada:

\n\n
<key>CFBundleURLTypes</key>\n<array>\n    <dict>\n        <key>CFBundleURLSchemes</key>\n        <array>\n            <string>com.googleusercontent.apps.YOUR_CLIENT_ID</string>\n        </array>\n    </dict>\n</array>
\n\n

Paso 2. Código de autorización

\n\n
import OAuthSwift\n\nlet oauthswift = OAuth2Swift(\n    consumerKey:    "YOUR_CLIENT_ID",\n    consumerSecret: "YOUR_CLIENT_SECRET",\n    authorizeUrl:   "https://accounts.google.com/o/oauth2/auth",\n    accessTokenUrl: "https://oauth2.googleapis.com/token",\n    responseType:   "code"\n)\n\n// Guardamos la referencia al controlador para presentar el WebView\nlet handler = SafariURLHandler(viewController: self, oauthSwift: oauthswift)\noauthswift.authorizeURLHandler = handler\n\nlet state = generateState(withLength: 20)\noauthswift.authorize(\n    withCallbackURL: URL(string: "com.googleusercontent.apps.YOUR_CLIENT_ID:/oauth2callback")!,\n    scope: "https://www.googleapis.com/auth/userinfo.email",\n    state: state,\n    parameters: [:]) { result in\n    switch result {\n    case .success(let (credential, response, parameters)):\n        print("Access Token: \\(credential.oauthToken)")\n        print("Refresh Token: \\(credential.oauthRefreshToken)")\n        // Guardamos los tokens en Keychain\n        KeychainWrapper.standard.set(credential.oauthToken, forKey: "access_token")\n        KeychainWrapper.standard.set(credential.oauthRefreshToken, forKey: "refresh_token")\n    case .failure(let error):\n        print("Error de autorización: \\(error.localizedDescription)")\n                    

Recommendations