Bearer token en Rust avec reqwest

Bearer token en Rust avec reqwest

Afin d'effectuer des requêtes API vers un serveur, il est parfois nécessaire de s'authentifier auprès de cette API avec le mécanisme "Bearer token".

Si vous utilisez la bibliothèque reqwest pour effectuer vos requêtes HTTP, le client reqwest::Client permet de spécifier un token à utiliser pour les requêtes. Pour cela, on effectue une première authentification sur le formulaire de connexion :

use serde::Deserialize;
use std::collections::HashMap;

async fn main() {
    let url = "https://example.org/login";
    let client = reqwest::Client::new();
    let mut login_data = HashMap::new();
    login_data.insert("username", "titi");
    login_data.insert("password", "toto");

    // Soumission du formulaire
    let response = client
        .post(url)
        .json(&login_data)
        .send()
        .await
        .expect("Impossible de récupérer la réponse");
    let token_str = response.text().await.unwrap();
    let api: API = serde_json::from_str(&token_str).unwrap();
}

#[derive(Deserialize)]
struct API {
    token: String,
}

Une fois cette authentification effectuée, il suffit de redonner le token au client lors des requêtes suivantes :

async fn main() {
    ...
    let mut query_data = HashMap::new();
    query_data.insert("equipe", "42");
    let response = client
        .post("https://example.org/something")
        .bearer_auth(&api.token)
        .json(&query_data)
        .send()
        .await;
}

J'imagine qu'on doit pouvoir fixer le token pour le reqwest::Client entier et pas juste la requête, mais je n'ai pas trouvé comment.

EDIT: En effet c'est possible en utilisant le builder du client de cette manière :

use reqwest::header;
[...]
     // Configure Client
     let mut headers = header::HeaderMap::new();
     headers.insert(
         header::AUTHORIZATION,
         format!("Bearer {}", token_str)
             .parse()
             .expect("Can't parse formatted token into a HeaderName"),
     );
     let client = reqwest::Client::builder()
         .default_headers(headers)
         .build()
         .unwrap();
[...] 

Merci à @Mattherix@mamot.fr pour sa contribution !