接入google play token 校验
This commit is contained in:
parent
a99589283a
commit
c51f80b2f3
@ -45,6 +45,10 @@ pub struct GoogleJwtProfile {
|
||||
pub given_name: String,
|
||||
pub family_name: String,
|
||||
pub locale: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub google_play_games_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub google_play_games_profile: Option<String>,
|
||||
}
|
||||
|
||||
impl GoogleJwtProfile {
|
||||
@ -159,4 +163,76 @@ impl GoogleSocial {
|
||||
|
||||
Ok(google_jwt_profile)
|
||||
}
|
||||
|
||||
/// 验证 Google Play Games 的身份信息
|
||||
/// 参考: https://developers.google.com/games/services/android/signin
|
||||
pub async fn verify_play_games_token(&self, play_games_token: &str) -> SocialResult<GoogleJwtProfile> {
|
||||
// Google Play Games 的验证端点
|
||||
const GOOGLE_PLAY_GAMES_TOKEN_INFO_URL: &str =
|
||||
"https://oauth2.googleapis.com/tokeninfo";
|
||||
|
||||
let client = Client::new();
|
||||
let response = client
|
||||
.get(GOOGLE_PLAY_GAMES_TOKEN_INFO_URL)
|
||||
.query(&[("access_token", play_games_token)])
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(Box::new(ResErr::social("验证 Google Play Games Token 失败")));
|
||||
}
|
||||
|
||||
let token_info: Value = response.json().await?;
|
||||
|
||||
// 验证 token 信息
|
||||
if let Some(error) = token_info.get("error") {
|
||||
return Err(Box::new(ResErr::social(format!(
|
||||
"Google Play Games Token 无效: {}",
|
||||
error
|
||||
))));
|
||||
}
|
||||
|
||||
// 验证 audience 是否匹配你的应用
|
||||
if let Some(aud) = token_info.get("aud") {
|
||||
// TODO: 验证 aud 是否匹配你的 Google Play Games 应用 ID
|
||||
tracing::debug!("Google Play Games aud: {}", aud);
|
||||
}
|
||||
|
||||
// 构建用户资料
|
||||
let mut profile = GoogleJwtProfile::default();
|
||||
if let Some(sub) = token_info.get("sub").and_then(|v| v.as_str()) {
|
||||
profile.sub = sub.to_string();
|
||||
}
|
||||
if let Some(email) = token_info.get("email").and_then(|v| v.as_str()) {
|
||||
profile.email = email.to_string();
|
||||
}
|
||||
|
||||
// 获取 Google Play Games 特定的信息
|
||||
let play_games_info = self.fetch_play_games_profile(play_games_token).await?;
|
||||
profile.google_play_games_id = play_games_info.get("playerId")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(String::from);
|
||||
|
||||
Ok(profile)
|
||||
}
|
||||
|
||||
/// 获取 Google Play Games 用户资料
|
||||
async fn fetch_play_games_profile(&self, access_token: &str) -> SocialResult<Value> {
|
||||
const PLAY_GAMES_PROFILE_URL: &str =
|
||||
"https://games.googleapis.com/games/v1/players/me";
|
||||
|
||||
let client = Client::new();
|
||||
let response = client
|
||||
.get(PLAY_GAMES_PROFILE_URL)
|
||||
.header("Authorization", format!("Bearer {}", access_token))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(Box::new(ResErr::social("获取 Google Play Games 用户资料失败")));
|
||||
}
|
||||
|
||||
let profile: Value = response.json().await?;
|
||||
Ok(profile)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user