Introdução ao OAuth 2.0 e JWT em Swift
\n\nAplicativos móveis e desktop modernos raramente funcionam sem autenticação. Dois protocolos-chave — OAuth 2.0 e JWT (JSON Web Token) — tornaram-se o padrão de facto para a transferência segura de dados entre cliente e servidor. Neste artigo, vamos analisar como implementar a autorização OAuth 2.0 e JWT em Swift para as plataformas iOS e macOS. Você aprenderá como configurar o fluxo de obtenção de tokens, armazená-los no Keychain e renová-los automaticamente quando expirarem.
\n\nO artigo é voltado para desenvolvedores iniciantes que já estão familiarizados com os fundamentos do Swift e SwiftUI. Usaremos URLSession para requisições de rede e Keychain para armazenamento seguro de dados. O código é escrito em Swift 5.9 e é compatível com iOS 15+ / macOS 12+.
\n\nO que são OAuth 2.0 e JWT?
\n\nAntes de escrever código, vamos entender a teoria.
\n\nOAuth 2.0
\nOAuth 2.0 é um protocolo de autorização que permite que um aplicativo obtenha acesso limitado aos recursos de um usuário sem transmitir seu login e senha. Em vez disso, são usados tokens de acesso. Os principais participantes são:
\n- \n
- Resource Owner — o usuário. \n
- Client — seu aplicativo. \n
- Authorization Server — servidor que emite tokens. \n
- Resource Server — API que fornece dados. \n
O fluxo mais popular para aplicativos móveis é o Authorization Code Flow with PKCE (Proof Key for Code Exchange). Ele é seguro mesmo sem um client secret, que é difícil de armazenar no aplicativo.
\n\nJWT (JSON Web Token)
\nJWT é um formato de token compacto e autossuficiente que contém dados JSON. Ele consiste em três partes separadas por pontos:
\n- \n
- Header — tipo de token e algoritmo de assinatura. \n
- Payload — dados úteis (claims), como ID do usuário, função, prazo de validade. \n
- Signature — assinatura para verificar a integridade. \n
JWT é frequentemente usado como access token no OAuth 2.0. Ele permite que o servidor verifique a autenticidade da requisição sem consultar o banco de dados.
\n\nImplementação prática em Swift
\n\nVamos criar uma classe simples AuthService que gerenciará a autenticação. Para o exemplo, usaremos o servidor https://api.example.com.
Passo 1: Obtenção de tokens via OAuth 2.0
\n\nPrimeiro, implementaremos um método para obter tokens a partir do código de autorização. Suponha que já recebemos o authorizationCode através de uma web view (por exemplo, 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: - Obtenção 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,