OAuth 2.0 e autorização JWT em Rust: guia passo a passo para iniciantes

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

Introdução

\n

O desenvolvimento web moderno é impensável sem autenticação e autorização seguras de usuários. Os dois padrões mais populares — OAuth 2.0 e JWT (JSON Web Tokens) — tornaram-se soluções industriais de facto. Se você programa em Rust, está com sorte: esta linguagem oferece não apenas o mais alto desempenho, mas também bibliotecas poderosas para implementar esses protocolos.

\n

Neste artigo, vamos explicar o que são OAuth 2.0 e JWT, como eles funcionam juntos e escrever um exemplo simples, mas funcional, de autorização em Rust usando o framework actix-web e a crate jsonwebtoken. O artigo é voltado para iniciantes, então vamos passo a passo — da teoria ao código.

\n\n

O que são OAuth 2.0 e JWT?

\n

Antes de escrever código, é importante entender os conceitos. OAuth 2.0 é um protocolo de autorização que permite que aplicativos obtenham acesso limitado aos recursos do usuário sem transmitir sua senha. Ele é usado quando você faz login em um site via Google, GitHub ou VK.

\n

JWT é um formato de token (JSON Object Signing and Encryption) que contém declarações (claims) sobre o usuário. O token é assinado pelo servidor, portanto o cliente não pode falsificá-lo. No contexto do OAuth 2.0, o JWT é frequentemente usado como access token (token de acesso).

\n

Cenário típico: o usuário insere login e senha, o servidor os verifica, gera um token JWT e o retorna ao cliente. O cliente envia este token em cada requisição no cabeçalho Authorization: Bearer <token>. O servidor verifica a assinatura e extrai os dados do usuário.

\n\n

Configuração do projeto em Rust

\n

Vamos criar um novo projeto:

\n
cargo new rust_oauth_jwt\ncd rust_oauth_jwt
\n

Adicione as dependências necessárias no Cargo.toml:

\n
[dependencies]\nactix-web = "4"\nactix-rt = "2"\nserde = { version = "1", features = ["derive"] }\nserde_json = "1"\njsonwebtoken = "9"\nchrono = { version = "0.4", features = ["serde"] }\ndotenv = "0.15"\nenv_logger = "0.11"\nlog = "0.4"
\n

Crie um arquivo .env na raiz do projeto para armazenar a chave secreta:

\n
JWT_SECRET=my_super_secret_key_change_in_production\nJWT_EXPIRATION_HOURS=24
\n

Carregue as variáveis de ambiente no main.rs:

\n
use dotenv::dotenv;\nuse std::env;\n\nfn main() {\n    dotenv().ok();\n    env_logger::init();\n    // ... resto do código\n}
\n\n

Criação da estrutura do usuário e do token JWT

\n

Primeiro, vamos definir o modelo de usuário e a estrutura de claims para o JWT. Crie o arquivo models.rs:

\n
use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize, Clone)]\npub struct User {\n    pub id: i32,\n    pub username: String,\n    pub password_hash: String, // Em um projeto real, armazene o hash, não a senha!\n}\n\n#[derive(Debug, Serialize, Deserialize)]\npub struct Claims {\n    pub sub: String,       // subject (id do usuário)\n    pub username: String,\n    pub exp: usize,        // timestamp de expiração\n}
\n

Agora, crie um utilitário para trabalhar com JWT em jwt_utils.rs:

\n
use chrono::{Duration, Utc};\nuse jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};\nuse crate::models::Claims;\n\npub fn create_jwt(user_id: &str, username: &str) -> Result<String, jsonwebtoken::errors::Error> {\n    let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET must be set");\n    let expiration_hours: i64 = std::env::var("JWT_EXPIRATION_HOURS")\n        .unwrap_or_else(|_| "24".to_string())\n        .parse()\n        .unwrap();\n\n    let expiration = Utc::now()\n        .checked_add_signed(Duration::hours(expiration_hours))\n        .expect("valid timestamp")\n        .timestamp() as usize;\n\n    let claims = Claims {\n        sub: user_id.to_owned(),\n        username: username.to_owned(),\n                

Blogs

Book Recommendations