Introdução: por que a autorização é necessária em Rust?
Aplicações web modernas raramente funcionam sem um sistema de autenticação e autorização. Rust, graças ao seu desempenho e segurança de memória, está se tornando uma escolha popular para criar serviços de alta carga. No entanto, trabalhar com protocolos como OAuth 2.0 e o formato JWT pode parecer complexo para iniciantes.
Neste artigo, vamos explorar os conceitos básicos de OAuth 2.0 e JWT (JSON Web Token) e implementar um sistema simples de autorização em Rust usando crates populares. Você aprenderá como proteger seus endpoints de API e trabalhar com tokens de acesso.
O que são OAuth 2.0 e JWT?
Antes de escrever código, é importante entender a teoria.
OAuth 2.0: protocolo de acesso delegado
OAuth 2.0 é um protocolo que permite que uma aplicação obtenha acesso limitado aos recursos de um usuário sem transmitir seu login e senha. Imagine que você queira entrar em um site através do Google ou GitHub — isso é OAuth 2.0.
Principais participantes do protocolo:
- Resource Owner — o usuário que possui os dados.
- Client — sua aplicação em Rust que deseja obter acesso.
- Authorization Server — o servidor que emite tokens (ex.: Google).
- Resource Server — a API que fornece os dados (ex.: Google Drive).
JWT: formato compacto de token
JWT (JSON Web Token) é um padrão aberto para criar tokens de acesso. O token consiste em três partes separadas por pontos:
- Header — tipo de token e algoritmo de assinatura.
- Payload — dados (claims), como ID do usuário ou função.
- Signature — assinatura que garante que o token não foi alterado.
Exemplo de JWT: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNrxP0G7n9G4W7N8Y7J8
JWT é conveniente porque não requer armazenamento de sessões no servidor — todas as informações já estão embutidas no token.
Configuração do projeto Rust para autorização
Usaremos o framework Actix Web e alguns crates auxiliares. Crie um novo projeto:
cargo new rust-auth-examplecd rust-auth-exampleAdicione as dependências no Cargo.toml:
[dependencies]actix-web = "4"actix-rt = "2"serde = { version = "1", features = ["derive"] }serde_json = "1"jsonwebtoken = "9"chrono = { version = "0.4", features = ["serde"] }dotenv = "0.15"env_logger = "0.10"bcrypt = "0.15"Estrutura de arquivos
Para facilitar, criaremos uma estrutura modular:
src/├── main.rs├── auth.rs├── models.rs└── handlers.rsNo .env, definiremos a chave secreta para JWT:
JWT_SECRET=supersecretkey12345DATABASE_URL=sqlite://users.dbImplementação de JWT em Rust: da geração à verificação
Vamos começar com o módulo auth.rs, que será responsável pelo trabalho com JWT.
Estruturas para JWT
// auth.rsuse serde::{Deserialize, Serialize};use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};use chrono::{Utc, Duration};
#[derive(Debug, Serialize, Deserialize)]pub struct Claims { pub sub: String, // ID do usuário pub exp: usize, // tempo de expiração pub iat: usize, // tempo de emissão}
pub fn create_jwt(user_id: &str, secret: &str) -> Result<String, jsonwebtoken::errors::Error> { let now = Utc::now(); let expiration = now + Duration::hours(24); // token válido por 24 horas
let claims = Claims { sub: user_id.to_owned(), exp: expiration.timestamp() as usize, iat: now.timestamp() as usize, };
let token = encode( &Header::default(), &claims,\