From 4e0c5fbfdc7d0df33e1af944323cc9aad7d753c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=BF=90=E5=AE=B6?= Date: Wed, 29 May 2024 12:34:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=85=AC=E9=92=A5=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/src/social/google.rs | 72 +++++++++++++----------------------- 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/library/src/social/google.rs b/library/src/social/google.rs index fe28887..42b9453 100644 --- a/library/src/social/google.rs +++ b/library/src/social/google.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use chrono::Utc; use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation}; use reqwest::Client; +use serde::Deserialize; use serde_json::Value; use crate::resp::response::ResErr; @@ -92,53 +93,34 @@ impl From for GoogleJwtProfile { } } -// 异步获取并解析Google公钥 -async fn fetch_and_parse_google_public_keys() -> SocialResult> { - let response = Client::new().get(GOOGLE_PUBLIC_CERT_URL).send().await?; - let google_keys: Value = response.json().await?; +#[derive(Deserialize, Debug, Clone)] +struct GooglePublicKey { + e: String, + n: String, + kty: String, + use_: String, + alg: String, + kid: String, +} - /* Google公钥结构如下: - { - "keys": [ - { - "e": "AQAB", - "n": "xjWd1j8GmmWzuz732haG9HECXsSZBvxOBLph3FQhk_tplhWloI1ywx-RdopUZt1lndbOM9n99lZJkpQyNJ1sdy7JFgYLjqj-wtHdEaQlBGEQtmkW8zUjr_N3bmpsxGbPzOzlKe3qddtoxXvn9rI_RvHfJD1YY-6kayQeyPOBz_4ML1lvI_JHV-Bb1MSmSk3WaAh5PzeqleusmUT87Gqfu02cOPrY8cwugqo65D6-wzAEeVvceV8-c36TMoLU5csU05GBVplgd6Ouuw35ZsETG4si4QQJztC3KsZ4jhYM-aJ3jeFPt0r3cQooiXdZBp3JkXSpE-UUaOVPsXo7WiVmww", - "kty": "RSA", - "use": "sig", - "alg": "RS256", - "kid": "323b214ae6975a0f034ea77354dc0c25d03642dc" - }, - { - "kid": "6719678351a5faedc2e70274bbea62da2a8c4a12", - "n": "oAP5OnSzKfkEV2QMm2XCuu4G8VGRBOyhKg-4H04WzYzPqM_Tmqi60Vod96JTo7SfM0OoGeNnlkWNjjBWkSS66alNLrvTNLi0A-KGeBsZiIFmrbsP6HHJfFzPd0Mci7-e11fNKecZgbC1me9PtRXFZb9JprZGFOvBiMwU0rRvh0GWYmTFj1HFjOIMAwTGOKOVGNuPjv0b3V0YaAkUNklzi4MM6qgzUb0tE0so1Ii7kBe7roMScS2USPeeJkeoPjLEbQcrT8MxOSxH-JgPLfq-zOnEJ6ERW3mtXdZCNzqmVLn5yjX5lKr5E2vgkPAHx9NLZ09fo_L9woeX_5epl6cIkQ", - "use": "sig", - "alg": "RS256", - "kty": "RSA", - "e": "AQAB" - } - ] - } - */ - tracing::info!("Google公钥获取成功, {}", google_keys); +#[derive(Deserialize, Debug, Clone)] +struct GooglePublicKeys { + keys: Vec, +} + +// 异步获取并解析Google公钥 +async fn fetch_and_parse_google_public_keys() -> SocialResult> { + let response = Client::new().get(GOOGLE_PUBLIC_CERT_URL).send().await?; + let google_keys: GooglePublicKeys = response.json().await?; + tracing::info!("Google公钥获取成功, {:?}", google_keys); let mut key_map = HashMap::new(); // 解析公钥 - google_keys - .get("keys") - .and_then(serde_json::Value::as_array) - .unwrap() - .iter() - .for_each(|key| { - if key - .get("kty") - .map(|kty| kty.as_str() == Some("RSA")) - .unwrap() - { - let n = key.get("n").unwrap().as_str().unwrap(); - let kid = key.get("kid").unwrap().as_str().unwrap(); - key_map.insert(kid.to_string(), key.clone()); - } - }); + for key in google_keys.keys.iter() { + if key.kty == "RSA" { + key_map.insert(key.kid.to_owned(), key.to_owned()); + } + } tracing::info!("Google公钥解析成功, {:?}", key_map); Ok(key_map) @@ -165,8 +147,6 @@ pub async fn verify_id_token(id_token: &str) -> SocialResult { .ok_or_else(|| Box::new(ResErr::social("校验Token失败,未找到正确的公钥")))?; tracing::info!("public key : {:?}", key); - let n = key.get("n").unwrap().as_str().unwrap(); - let e = &key.get("e").unwrap().as_str().unwrap(); // 验证Token let mut validation: Validation = Validation::new(Algorithm::RS256); @@ -175,7 +155,7 @@ pub async fn verify_id_token(id_token: &str) -> SocialResult { let decoded = decode::( id_token, - &DecodingKey::from_rsa_components(n, e).unwrap(), + &DecodingKey::from_rsa_components(key.n.as_str(), key.e.as_str()).unwrap(), &validation, )?;