优化google.rs
This commit is contained in:
parent
9bdbe32311
commit
139536924d
@ -31,6 +31,13 @@ pub struct GoogleSocial {
|
|||||||
// 假设GOOGLE_PUBLIC_CERT_URL是Google提供的公钥URL
|
// 假设GOOGLE_PUBLIC_CERT_URL是Google提供的公钥URL
|
||||||
const GOOGLE_PUBLIC_CERT_URL: &str = "https://www.googleapis.com/oauth2/v3/certs";
|
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)]
|
#[derive(Debug, Default, Deserialize)]
|
||||||
pub struct GoogleJwtProfile {
|
pub struct GoogleJwtProfile {
|
||||||
// iss (issuer):签发人
|
// iss (issuer):签发人
|
||||||
@ -186,61 +193,41 @@ impl GoogleSocial {
|
|||||||
// 1. 创建 OAuth2 client
|
// 1. 创建 OAuth2 client
|
||||||
let client = BasicClient::new(ClientId::new(config!().social.google.client_id.clone()))
|
let client = BasicClient::new(ClientId::new(config!().social.google.client_id.clone()))
|
||||||
.set_client_secret(ClientSecret::new(config!().social.google.client_secret.clone()))
|
.set_client_secret(ClientSecret::new(config!().social.google.client_secret.clone()))
|
||||||
.set_auth_uri(AuthUrl::new(
|
.set_auth_uri(AuthUrl::new(GOOGLE_AUTH_URL.to_string())?)
|
||||||
"https://accounts.google.com/o/oauth2/v2/auth".to_string(),
|
.set_token_uri(TokenUrl::new(GOOGLE_TOKEN_URL.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(),
|
|
||||||
)?)
|
|
||||||
// Google supports OAuth 2.0 Token Revocation (RFC-7009)
|
// Google supports OAuth 2.0 Token Revocation (RFC-7009)
|
||||||
.set_revocation_url(
|
.set_revocation_url(
|
||||||
RevocationUrl::new("https://oauth2.googleapis.com/revoke".to_string())
|
RevocationUrl::new(GOOGLE_REVOCATION_URL.to_string())
|
||||||
.expect("Invalid revocation endpoint URL"),
|
.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
|
// 2. 执行 token exchange
|
||||||
let token_response = client
|
let token_response = client
|
||||||
.exchange_code(AuthorizationCode::new(play_games_token.to_string()))
|
.exchange_code(AuthorizationCode::new(play_games_token.to_string()))
|
||||||
.set_pkce_verifier(pkce_code_verifier)
|
|
||||||
.request_async(&reqwest::Client::new())
|
.request_async(&reqwest::Client::new())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let access_token = token_response.access_token();
|
let access_token = token_response.access_token();
|
||||||
|
|
||||||
// 3. 使用新的 access token 获取用户信息
|
// 3. 获取用户信息和额外信息
|
||||||
let mut profile = self.fetch_play_games_profile(access_token.secret()).await?;
|
let mut profile = self.fetch_play_games_profile(access_token.secret()).await?;
|
||||||
|
self.enrich_profile_with_additional_info(&mut 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)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(profile)
|
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 用户资料
|
/// 获取 Google Play Games 用户资料
|
||||||
async fn fetch_play_games_profile(&self, access_token: &str) -> SocialResult<GoogleJwtProfile> {
|
async fn fetch_play_games_profile(&self, access_token: &str) -> SocialResult<GoogleJwtProfile> {
|
||||||
const PLAY_GAMES_PROFILE_URL: &str = "https://games.googleapis.com/games/v1/players/me";
|
const PLAY_GAMES_PROFILE_URL: &str = "https://games.googleapis.com/games/v1/players/me";
|
||||||
|
Loading…
Reference in New Issue
Block a user