Autenticação Segura em Rust: Construindo um Backend Protegido

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que Rust é a escolha ideal para autenticação?

\n\n

Se você está escrevendo uma aplicação web em Rust, já está um passo à frente em segurança. Rust não perdoa erros de memória, o que significa que muitas vulnerabilidades (estouro de buffer, use-after-free) são eliminadas em tempo de compilação. Mas o compilador não vai protegê-lo de uma lógica de autenticação ruim. É sobre isso — como construir autenticação segura em Rust usando práticas modernas.

\n\n

Neste artigo, montaremos um módulo de autenticação completo: hash de senhas com bcrypt, emissão de tokens JWT, verificação via middleware no Actix-web e proteção contra ataques comuns. O código será funcional — pode usá-lo no seu projeto.

\n\n

1. Hash de senhas: por que bcrypt e não SHA-256?

\n\n

Muitos iniciantes pensam: "Vou usar SHA-256, é rápido e confiável". E isso é um erro fatal. SHA é uma função de hash criptográfico, mas é rápida demais. Um atacante pode testar bilhões de combinações por segundo. Precisamos de uma função lenta, projetada especificamente para senhas.

\n\n

bcrypt é o padrão ouro. Ele inclui "sal" (salt) e "fator de custo" (cost factor), que pode ser aumentado conforme o poder computacional cresce.

\n\n

Adicionando bcrypt ao Cargo.toml

\n
[dependencies]\nbcrypt = "0.15"
\n\n

Gerando hash da senha

\n
use bcrypt::{hash, verify, DEFAULT_COST};\n\nfn hash_password(plain: &str) -> Result<String, bcrypt::BcryptError> {\n    hash(plain, DEFAULT_COST) // cost = 12 (padrão)\n}\n\nfn verify_password(plain: &str, hashed: &str) -> bool {\n    verify(plain, hashed).unwrap_or(false)\n}
\n\n

Observe: verify extrai o sal do próprio hash. Você não precisa armazenar o sal separadamente — ele já está dentro da string do hash. Isso é seguro e prático.

\n\n

2. Tokens JWT: como não falhar na autenticação

\n\n

Após o usuário digitar a senha, devemos emitir um "passe". JWT (JSON Web Token) é um formato compacto e autossuficiente. Mas o diabo está nos detalhes:

\n\n
    \n
  • Não armazene a chave secreta no código. Use variáveis de ambiente.
  • \n
  • Defina um tempo de vida curto. Token de acesso — 15–30 minutos, token de atualização — 7–30 dias.
  • \n
  • Não insira dados sensíveis no payload. Apenas o ID do usuário e a função.
  • \n
\n\n

Implementação de JWT com jsonwebtoken

\n\n
use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};\nuse serde::{Serialize, Deserialize};\nuse chrono::{Utc, Duration};\n\n#[derive(Debug, Serialize, Deserialize)]\npub struct Claims {\n    pub sub: String,       // ID do usuário\n    pub exp: usize,        // timestamp de expiração\n    pub iat: usize,        // emitido em\n}\n\npub fn create_token(user_id: &str, secret: &str) -> Result<String, jsonwebtoken::errors::Error> {\n    let now = Utc::now();\n    let claims = Claims {\n        sub: user_id.to_owned(),\n        exp: (now + Duration::minutes(30)).timestamp() as usize,\n        iat: now.timestamp() as usize,\n    };\n    encode(&Header::default(), &claims, &EncodingKey::from_secret(secret.as_bytes()))\n}\n\npub fn validate_token(token: &str, secret: &str) -> Result<Claims, jsonwebtoken::errors::Error> {\n    let token_data = decode::<Claims>(\n        token,\n        &DecodingKey::from_secret(secret.as_bytes()),\n        &Validation::default(),\n    )?;\n    Ok(token_data.claims)\n}
\n\n

3. Juntando tudo: Actix-web + middleware

\n\n

Agora vamos combinar hash e JWT em uma aplicação web completa com Actix-web. Vamos escrever um middleware que verifica o token em cada requisição protegida.

\n\n

Estrutura do projeto

\n
src/\n├── main.rs\n├── auth.rs       # hash, JWT\n├── middleware.rs # verificação de token\n└── handlers.rs   #                

Blogs

Book Recommendations