From 139536924dc4622d7415d140258b8eb3f357e7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=BF=90=E5=AE=B6?= Date: Thu, 23 Jan 2025 14:15:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96google.rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/src/social/google.rs | 61 ++++++++++++++---------------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/library/src/social/google.rs b/library/src/social/google.rs index db0bd21..59c77c8 100644 --- a/library/src/social/google.rs +++ b/library/src/social/google.rs @@ -31,6 +31,13 @@ pub struct GoogleSocial { // 假设GOOGLE_PUBLIC_CERT_URL是Google提供的公钥URL const GOOGLE_PUBLIC_CERT_URL: &str = "https://www.googleapis.com/oauth2/v3/certs"; +// Google OAuth2 相关常量 +const GOOGLE_AUTH_URL: &str = "https://accounts.google.com/o/oauth2/v2/auth"; +const GOOGLE_TOKEN_URL: &str = "https://oauth2.googleapis.com/token"; +const GOOGLE_REVOCATION_URL: &str = "https://oauth2.googleapis.com/revoke"; +const GOOGLE_GAMES_SCOPE: &str = "https://www.googleapis.com/auth/games"; +const GOOGLE_PROFILE_SCOPE: &str = "https://www.googleapis.com/auth/userinfo.profile"; + #[derive(Debug, Default, Deserialize)] pub struct GoogleJwtProfile { // iss (issuer):签发人 @@ -186,61 +193,41 @@ impl GoogleSocial { // 1. 创建 OAuth2 client let client = BasicClient::new(ClientId::new(config!().social.google.client_id.clone())) .set_client_secret(ClientSecret::new(config!().social.google.client_secret.clone())) - .set_auth_uri(AuthUrl::new( - "https://accounts.google.com/o/oauth2/v2/auth".to_string(), - )?) - .set_token_uri(TokenUrl::new( - "https://oauth2.googleapis.com/token".to_string(), - )?) - .set_redirect_uri(RedirectUrl::new( - "http://localhost:8080/auth/google/callback".to_string(), - )?) + .set_auth_uri(AuthUrl::new(GOOGLE_AUTH_URL.to_string())?) + .set_token_uri(TokenUrl::new(GOOGLE_TOKEN_URL.to_string())?) // Google supports OAuth 2.0 Token Revocation (RFC-7009) .set_revocation_url( - RevocationUrl::new("https://oauth2.googleapis.com/revoke".to_string()) + RevocationUrl::new(GOOGLE_REVOCATION_URL.to_string()) .expect("Invalid revocation endpoint URL"), ); - // Google supports Proof Key for Code Exchange (PKCE - https://oauth.net/2/pkce/). - // Create a PKCE code verifier and SHA-256 encode it as a code challenge. - let (pkce_code_challenge, pkce_code_verifier) = PkceCodeChallenge::new_random_sha256(); - - // Generate the authorization URL to which we'll redirect the user. - let (_authorize_url, _csrf_state) = client - .authorize_url(CsrfToken::new_random) - // This example is requesting access to the "calendar" features and the user's profile. - .add_scope(Scope::new( - "https://www.googleapis.com/auth/calendar".to_string(), - )) - .add_scope(Scope::new( - "https://www.googleapis.com/auth/plus.me".to_string(), - )) - .set_pkce_challenge(pkce_code_challenge) - .url(); - // 2. 执行 token exchange let token_response = client .exchange_code(AuthorizationCode::new(play_games_token.to_string())) - .set_pkce_verifier(pkce_code_verifier) .request_async(&reqwest::Client::new()) .await?; let access_token = token_response.access_token(); - // 3. 使用新的 access token 获取用户信息 + // 3. 获取用户信息和额外信息 let mut profile = self.fetch_play_games_profile(access_token.secret()).await?; - - // 4. 获取额外的用户信息(如果需要) - if let Some(additional_info) = self - .fetch_additional_player_info(access_token.secret()) - .await? - { - profile.google_play_games_profile = Some(serde_json::to_string(&additional_info)?); - } + self.enrich_profile_with_additional_info(&mut profile, access_token.secret()).await?; Ok(profile) } + /// 使用额外信息丰富用户资料 + async fn enrich_profile_with_additional_info( + &self, + profile: &mut GoogleJwtProfile, + access_token: &str, + ) -> SocialResult<()> { + if let Some(additional_info) = self.fetch_additional_player_info(access_token).await? { + profile.google_play_games_profile = Some(serde_json::to_string(&additional_info)?); + } + Ok(()) + } + /// 获取 Google Play Games 用户资料 async fn fetch_play_games_profile(&self, access_token: &str) -> SocialResult { const PLAY_GAMES_PROFILE_URL: &str = "https://games.googleapis.com/games/v1/players/me";