firebase_admin_rust_auth/
lib.rs

1#[derive(Debug, serde::Serialize, serde::Deserialize)]
2pub struct DecodedIdToken {
3    pub aud: String,
4    pub auth_time: usize,
5    pub exp: usize,
6    pub iat: usize,
7    pub iss: String,
8    pub sub: String,
9}
10
11pub async fn verify_id_token_with_project_id(
12    token: &str,
13    project_id: &str,
14) -> Result<DecodedIdToken, Box<dyn std::error::Error>> {
15    let header = match jsonwebtoken::decode_header(token) {
16        Ok(output) => output,
17        Err(_) => return Err(std::boxed::Box::from(String::from("Header"))),
18    };
19
20    if header.alg != jsonwebtoken::Algorithm::RS256 {
21        return Err(std::boxed::Box::from(String::from("Algorithm")));
22    }
23
24    let kid = match header.kid {
25        Some(value) => value,
26        None => return Err(std::boxed::Box::from(String::from("Kid"))),
27    };
28
29    let public_keys = reqwest::get(
30        "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com",
31    )
32    .await?
33    .json::<std::collections::HashMap<String, String>>()
34    .await?;
35
36    if !public_keys.contains_key(&kid) {
37        return Err(std::boxed::Box::from(String::from("Public Keys Kid")));
38    }
39
40    let public_key = match public_keys.get(&kid) {
41        Some(value) => value,
42        None => return Err(std::boxed::Box::from(String::from("Public Key"))),
43    };
44
45    /*
46    let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::RS256);
47    validation.set_audience(&[project_id.to_string()]);
48    validation.iss = Some(format!("https://securetoken.google.com/{}", project_id));
49    */
50
51    let decoded_id_token = match jsonwebtoken::dangerous_unsafe_decode::<DecodedIdToken>(&token) {
52        Ok(value) => value.claims,
53        Err(error) => return Err(std::boxed::Box::from(format!("{:?}", error))),
54    };
55
56    Ok(decoded_id_token)
57}