Capítulo 09: Autenticação de API com Laravel Sanctum (Bearer Tokens)
Especialização em Backend com PHP & Laravel • Laravel 11 & PHP 8.3+ • Eloquent ORM, Sanctum, Filas, Horizon e APIs Corporativas
🗺️ Mapa Conceitual do Tópico
flowchart TD
A["Cliente envia email+senha"] --> B["Hash::check() valida credencial"]
B --> C["user->createToken('nome')->plainTextToken"]
C --> D["Token em texto puro devolvido 1 única vez"]
D --> E["Cliente envia Authorization: Bearer {token}"]
E --> F["Middleware auth:sanctum valida hash SHA-256"]
F --> G["Rota protegida executa com $request->user()"]
subgraph SCOPE["Controle Granular"]
H["createToken('app', ['produtos:read'])"]
I["$user->tokenCan('produtos:write')"]
J["currentAccessToken()->delete() — logout"]
end
G --> SCOPE
style A fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px
style C fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style F fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style I fill:#fce4ec,stroke:#e91e63,stroke-width:2px
🏛️ 1. Personal Access Tokens: Como o Sanctum Funciona
O Sanctum resolve dois cenários de autenticação: SPAs first-party (via cookies de sessão + CSRF) e APIs consumidas por mobile/terceiros (via Bearer Tokens). O segundo é o mais comum em APIs RESTful puras.
O modelo User recebe a trait HasApiTokens, que adiciona o método createToken(). Esse método gera uma string aleatória de alta entropia, mas só a versão em texto puro é retornada ao cliente uma única vez — o banco (personal_access_tokens) armazena apenas o hash SHA-256 dela:
<?php
public function login(Request $request)
{
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
return response()->json(['erro' => 'Credenciais inválidas'], 401);
}
$token = $user->createToken('api-token')->plainTextToken;
return response()->json(['token' => $token, 'token_type' => 'Bearer']);
}
Isso significa que, se o token vazar de um log ou banco de dados comprometido, ele é inútil sem o valor original — mesma lógica de segurança usada para senhas com bcrypt.
🛡️ 2. Protegendo Rotas com o Guard sanctum
O middleware auth:sanctum intercepta o header Authorization: Bearer {token}, calcula o hash e busca correspondência na tabela de tokens. Se válido, popula $request->user() com o dono do token para o restante do ciclo de vida da requisição:
// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn (Request $request) => $request->user());
Route::post('/logout', [AuthController::class, 'logout']);
});
Uma requisição sem token, com token expirado ou revogado recebe automaticamente 401 Unauthorized — a rota nunca chega a executar.
🎯 3. Abilities: Escopos Granulares por Token
Diferente de uma sessão web onde o usuário “é” ou “não é” autenticado, tokens de API podem carregar habilidades (abilities) — um mesmo usuário pode emitir um token só de leitura para um script de relatório, e outro de leitura+escrita para o app oficial:
$token = $user->createToken('app-mobile', ['produtos:read', 'produtos:write'])->plainTextToken;
public function store(Request $request)
{
if (!$request->user()->tokenCan('produtos:write')) {
return response()->json(['erro' => 'Token sem permissão de escrita'], 403);
}
// ...
}
tokenCan() verifica a habilidade do token atual, não do usuário em geral — um mesmo usuário pode ter tokens simultâneos com escopos diferentes.
🚪 4. Revogação e Expiração
Tokens não expiram por padrão; a expiração é configurada em config/sanctum.php ('expiration' => 525600 minutos, por exemplo). Revogar é uma operação explícita de exclusão do registro:
// Logout apenas do dispositivo/token atual
$request->user()->currentAccessToken()->delete();
// Logout de todos os dispositivos simultaneamente
$request->user()->tokens()->delete();
Como a validação depende de uma consulta ao banco a cada requisição, revogar um token tem efeito imediato — ao contrário de JWTs stateless, que continuam válidos até expirarem, mesmo se “revogados” no lado do servidor.
🔗 Recursos Pedagógicos do Capítulo 09
| Recurso Didático | Finalidade | Link de Acesso |
|---|---|---|
| 📊 Slides de Aula | Apresentação visual interativa com Dark Mode e suporte a teclado | Ver Slides |
| 🧠 Quiz Formativo | Teste interativo de fixação com feedback imediato por alternativa | Fazer Quiz |
| 💻 Exemplos de Código | Demonstrações funcionais com código executável | Ver Exemplos |
| 🧩 Exercícios em 4 Níveis | Lista progressiva de fixação com gabarito em bloco colapsável | Resolver Exercícios |
| ⬅️ Capítulo Anterior | 📚 Sumário de Tópicos | Próximo Capítulo ➡️ |