Introdução: por que a autorização é necessária em aplicativos móveis?
Os aplicativos iOS modernos raramente funcionam isoladamente. Eles se comunicam com servidores, enviam dados, recebem conteúdo personalizado. Mas como o servidor sabe que a solicitação foi enviada pelo usuário que ele afirma ser? É aqui que entram em cena o OAuth 2.0 e o JWT (JSON Web Token). Estas não são apenas siglas da moda, mas padrões de segurança que fundamentam a maioria das APIs modernas (Google, Facebook, GitHub, seu próprio backend).
Neste artigo, vamos explorar como o OAuth 2.0 e o JWT funcionam em Swift. Você aprenderá como eles diferem, como implementá-los corretamente e quais armadilhas esperam um iniciante. Escreveremos código para obter, armazenar e atualizar tokens. Vamos lá!
1. Fundamentos: OAuth 2.0 e JWT — qual a diferença?
Muitas pessoas confundem esses dois conceitos. Na verdade, são níveis diferentes de abstração.
- OAuth 2.0 é um protocolo de autorização. Ele descreve como um aplicativo (cliente) pode obter acesso aos recursos de um usuário em um servidor de terceiros (por exemplo, suas fotos no Google) sem transmitir login e senha. A ideia principal é a emissão de tokens de acesso temporários.
- JWT é um formato de token. É uma string compacta e segura para URL que contém dados JSON (por exemplo, ID do usuário, função, data de expiração) e uma assinatura. O JWT é frequentemente usado como access token no OAuth 2.0, mas também pode ser usado separadamente.
Uma analogia simples: OAuth 2.0 são as regras para emitir um passe de entrada para o estádio, e JWT é o próprio passe de plástico com sua foto e carimbo.
Em um cenário típico, um aplicativo iOS:
- Abre um navegador para fazer login através de um provedor OAuth (Google, Apple ID, seu próprio servidor).
- Obtém um authorization code.
- Troca o código por um access token (frequentemente no formato JWT) e um refresh token.
- Usa o access token para fazer solicitações à API.
- Quando o access token expira, usa o refresh token para obter um novo.
2. Estrutura do token JWT
O JWT consiste em três partes, separadas por pontos:
header.payload.signatureExemplo de um JWT decodificado:
// Header (cabeçalho){ "alg": "HS256", "typ": "JWT"}// Payload (carga útil){ "sub": "1234567890", "name": "João Silva", "iat": 1516239022, "exp": 1516242622}// Signature (assinatura) - criada pelo servidorImportante: O Payload do JWT não é criptografado, ele é apenas codificado em Base64. Qualquer pessoa pode lê-lo. A segurança é fornecida pela assinatura — se o servidor perceber que a assinatura não corresponde, ele rejeita o token. Portanto, nunca armazene senhas ou dados secretos no JWT.
3. Implementação de OAuth 2.0 e JWT em Swift
Agora vamos para a prática. Escreveremos uma classe para trabalhar com autorização. Para simplificar, usaremos o URLSession embutido, embora em projetos reais frequentemente se use Alamofire ou SwiftUI + async/await.
3.1. Modelos de dados
struct AuthResponse: Codable { let accessToken: String let refreshToken: String? let expiresIn: Int enum CodingKeys: String, CodingKey { case accessToken = "access_token" case refreshToken = "refresh_token" case expiresIn = "expires_in" }}
struct UserProfile: Codable { let id: String let name: String let email: String}3.2. Serviço de autorização
Criaremos uma classe AuthService que será responsável por obter e atualizar tokens. Observe: em um aplicativo real, a URL e o clientSecret devem ser armazenados com segurança (por exemplo, no Keychain ou através de um servidor de configuração).
class AuthService { static let shared = A