Fase 5 6 horas Avançado

A Grande Corrida

Na reta final, só passa quem tem credencial. OAuth 2.0, OIDC e JWT são os portões da segurança digital — saber abri-los é chegar primeiro.

Fase 5 — A Grande Corrida · OAuth 2.0, OIDC e JWT
Progresso: 0/8 (0%)

Objetivos da Fase

O que você vai aprender:

  • OAuth 2.0: fluxo de autorização passo a passo
  • OIDC (OpenID Connect): identidade sobre OAuth
  • Estrutura de um JWT (header.payload.signature)
  • Scopes, claims e o princípio do menor privilégio
  • Diferença entre autenticação e autorização
  • Provedores OIDC: Google, GitHub, Microsoft
  • Biblioteca python-jose para JWT em Python

O que você vai criar:

  • Decodificador de JWT manual (base64url)
  • Simulador do fluxo OAuth 2.0
  • Validador de token OIDC com python-jose
  • Dashboard HTTP com rota protegida

5.1 — O Portão da Corrida: OAuth 2.0

Imagina a largada: o fiscal pede sua credencial, você apresenta sua identidade, ele emite um crachá temporário. Esse crachá é o access token.

🔑 Fluxo Authorization Code

  1. Usuário clica em "Entrar com Google"
  2. App redireciona para o provedor com client_id + scope
  3. Usuário autentica e autoriza
  4. Provedor retorna um authorization_code
  5. App troca o código por access_token + id_token
  6. App usa o token para acessar recursos protegidos
# Simulador do fluxo OAuth 2.0 em Python import urllib.parse, secrets CLIENT_ID = "circuito_ferradura_app" REDIRECT_URI = "http://localhost:8080/callback" SCOPE = "openid profile email" state = secrets.token_urlsafe(16) # proteção CSRF params = { "response_type": "code", "client_id": CLIENT_ID, "redirect_uri": REDIRECT_URI, "scope": SCOPE, "state": state, } url = "https://accounts.google.com/o/oauth2/auth?" + urllib.parse.urlencode(params) print(f"→ Redirecionar para:\n{url}")

5.2 — O Número do Peito: JWT

Cada piloto tem um número no peito — único e verificável. O JWT funciona assim: três partes separadas por ponto, codificadas em base64url.

# Estrutura de um JWT # HEADER.PAYLOAD.SIGNATURE # # Header → {"alg": "RS256", "typ": "JWT"} # Payload → {"sub": "12345", "name": "Ciclano", # "email": "ci@ferradura.dev", "iat": 1702930800} import base64, json def decodificar_jwt(token: str) -> dict: partes = token.split(".") def decode_b64(s): padding = 4 - len(s) % 4 return json.loads(base64.urlsafe_b64decode(s + "=" * padding)) header = decode_b64(partes[0]) payload = decode_b64(partes[1]) return {"header": header, "payload": payload, "assinatura": partes[2][:20] + "..."} # Exemplo com python-jose (validação com chave pública) from jose import jwt claims = jwt.decode(token, chave_publica, algorithms=["RS256"], audience=CLIENT_ID) print(f"Bem-vindo, {claims['name']}!")

5.3 — OIDC: A Identidade sobre o OAuth

OAuth diz "você pode acessar". OIDC responde "mas quem é você?". O id_token contém as claims de identidade verificáveis.

# Claims típicas de um id_token OIDC id_token_payload = { "iss": "https://accounts.google.com", # quem emitiu "sub": "103456789012345678901", # ID único do usuário "aud": CLIENT_ID, # para quem é o token "exp": 1702934400, # quando expira (Unix) "iat": 1702930800, # quando foi emitido "name": "Ciclano da Corrida", "email": "ciclano@ferradura.dev", "email_verified": True, } def piloto_autenticado(claims: dict) -> bool: import time return claims.get("email_verified") and claims["exp"] > time.time()

✅ Checklist da Fase 5

🔐 Projeto da Fase 5

Crie um micro-servidor Flask com duas rotas: /login (redireciona para Google OAuth) e /dashboard (protegida — exige id_token válido na sessão). Use python-jose para validar o token e exiba o nome do piloto autenticado.

🔒 LGPD — Usamos localStorage para salvar progresso.