Cliente OAuth para Rust: biblioteca oauth2-rs

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

Biblioteca oauth2-rs: implementação de OAuth 2.0 em Rust

No desenvolvimento web moderno, o OAuth 2.0 é o protocolo padrão para delegação de acesso. A biblioteca oauth2-rs oferece uma implementação completa de cliente OAuth 2.0 na linguagem Rust. Ela permite integrar autenticação através de serviços populares como Google, GitHub, Yandex, VK e outros.

Esta biblioteca suporta todos os principais fluxos (grants): Authorization Code, Client Credentials, Implicit, além de Refresh Token. A segurança é priorizada com o uso de PKCE (Proof Key for Code Exchange) para clientes públicos e validação obrigatória de tokens.

Instalação do oauth2-rs

Adicione a dependência no Cargo.toml:

[dependencies]
oauth2 = "4.4"
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }

Você também precisará de um cliente HTTP (recomendamos reqwest com suporte async) e do serializador serde para trabalhar com JSON.

Configuração básica do cliente OAuth

Vamos ver um exemplo para o Google OAuth 2.0. Primeiro, criamos a configuração:

use oauth2::{
    AuthorizationCode, AuthUrl, ClientId, ClientSecret, 
    RedirectUrl, TokenUrl, CsrfToken, Scope,
    basic::BasicClient, TokenResponse
};

let client_id = ClientId::new("SEU_GOOGLE_CLIENT_ID".to_string());
let client_secret = ClientSecret::new("SEU_GOOGLE_CLIENT_SECRET".to_string());
let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string())
    .expect("URL de autenticação inválida");
let token_url = TokenUrl::new("https://oauth2.googleapis.com/token".to_string())
    .expect("URL de token inválida");

let client = BasicClient::new(
    client_id,
    Some(client_secret),
    auth_url,
    Some(token_url)
).set_redirect_uri(
    RedirectUrl::new("http://localhost:8080/callback".to_string())
        .expect("URL de redirecionamento inválida")
);

Geração da URL de autorização

Criamos o link para onde o usuário deve ser redirecionado:

let (auth_url, csrf_token) = client
    .authorize_url(CsrfToken::new_random)
    .add_scope(Scope::new("openid".to_string()))
    .add_scope(Scope::new("email".to_string()))
    .url();

println!("Acesse o link: {}", auth_url);
// Salve o csrf_token para verificação no callback

O CsrfToken protege contra ataques de falsificação de solicitação entre sites (CSRF). Ele deve ser armazenado temporariamente (por exemplo, em sessão ou cookies) e verificado ao processar o callback.

Processamento do callback e obtenção do token

Após o usuário confirmar o acesso, o serviço o redirecionará para a redirect_uri com o parâmetro code. Exemplo de handler em Rust:

use actix_web::{web, HttpRequest, HttpResponse};
use oauth2::AuthorizationCode;

async fn callback(query: web::Query<std::collections::HashMap<String, String>>) -> HttpResponse {
    let code = query.get("code")
        .expect("Código de autorização ausente");
    let state = query.get("state")
        .expect("State ausente");

    // Verifique o state contra o csrf_token salvo
    // ...

    let token_result = client
        .exchange_code(AuthorizationCode::new(code.clone()))
        .request_async(&reqwest::Client::new())
        .await;

    match token_result {
        Ok(token) => {
            let access_token = token.access_token().secret();
            let refresh_token = token.refresh_token()
                .map(|rt| rt.secret().clone());
            // Salve os tokens no banco de dados ou sessão
            HttpResponse::Ok().body("Autenticação bem-sucedida!")
        },
        Err(e) => {
            eprintln!("Erro na troca do código: {:?}", e);
            HttpResponse::InternalServerError().body("Erro de autenticação")
        }
    }
}

Trabalhando com Refresh Tokens

Para manter a sessão ativa sem exigir que o usuário faça login novamente, utilize o refresh token:

use oauth2::RefreshToken;

let refresh_token = RefreshToken::new("SEU_REFRESH_TOKEN".to_string());

let token_result = client
    .exchange_refresh_token(&refresh_token)
    .request_async(&reqwest::Client::new())
    .await;

match token_result {
    Ok(new_token) => {
        let new_access_token = new_token.access_token().secret();
        println!("Novo access token: {}", new_access_token);
    },
    Err(e) => eprintln!("Erro ao renovar token: {:?}", e)
}

Considerações de segurança

Ao implementar OAuth 2.0 com Rust, lembre-se:

  • Nunca exponha client_secret em código front-end ou repositórios públicos
  • Sempre valide o state (CSRF token) no callback
  • Armazene tokens de acesso e refresh de forma segura (criptografados no banco de dados)
  • Use HTTPS em produção para todas as requisições
  • Implemente renovação automática de tokens expirados

A biblioteca oauth2-rs é uma solução robusta e segura para autenticação OAuth 2.0 em Rust, ideal para aplicações web, APIs e serviços que exigem integração com provedores de identidade.

Recommendations