Sign in with Google 账号认证(兼容 v1)
- 这是 Google 登录的 Web 认证方式,兼容 Google v1 方式。
- iOS、Android 均可使用。
- 建议使用 PlayNANOO SDK 5.0.0.6 及以上版本。(修复浏览器缓存问题)
- 最低要求版本:5.0.0.3
调用信息
Sign_in_with_Google(clientId)
调用详细信息
| 参数 | 说明 | 类型 |
|---|---|---|
| clientId | OAuth Web 客户端 ID | String |
源代码
using System;
using System.Threading.Tasks;
using Google;
using PlayNANOO;
public class PlayNANOOExample : MonoBehaviour
{
Plugin plugin;
private string clientId = "웹클라이언트 ID를 입력합니다.";
void Start()
{
plugin = Plugin.GetInstance();
// Android: DeepLink 콜백 등록
Application.deepLinkActivated += OnDeepLink;
}
// Android용 DeepLink 콜백
private void OnDeepLink(string url)
{
string token = ExtractIdToken(url);
if (!string.IsNullOrEmpty(token))
{
SendTokenToServer(token);
}
else
{
Debug.LogError("[GoogleOAuth] No id_token found in deep link!");
}
}
private string ExtractIdToken(string url)
{
if (!url.Contains("#")) return null;
string fragment = url.Split('#')[1];
string[] parts = fragment.Split('&');
foreach (var p in parts)
{
if (p.StartsWith("id_token="))
return p.Substring("id_token=".Length);
}
return null;
}
//인증 진행 메소드.
public void Sign_in_with_Google()
{
plugin.AccountManagerV20240401.SignInWithGoogle(clientId);
}
//인증 완료 시 토큰 받는 메소드.
private void SendTokenToServer(string token)
{
//toten 값으로 SocialChange 또는 SocialSignIn 진행.
//SocialChange(token, Configure.PN_ACCOUNT_GOOGLE);
// or
//SocialSignIn(token, Configure.PN_ACCOUNT_GOOGLE);
}
//계정 전환 예시. SocialChange
public void SocialChange(string token, string accountType)
{
//비회원 연동 - 회원 전환 참조.
plugin.AccountManagerV20240401.SocialChange(accessToken, accountType, (status, errorCode, jsonString, values) => {
}
}
//구글 계정 등록 예시. SocialSignIn
public void SocialSignIn(string token, string accountType)
{
plugin.AccountManagerV20240401.SocialSignIn(token, accountType, (status, errorCode, jsonString, values) =>
{
if (status == Configure.PN_API_STATE_SUCCESS)
{
Debug.Log(values["access_token"].ToString());
Debug.Log(values["refresh_token"].ToString());
Debug.Log(values["uuid"].ToString());
Debug.Log(values["openID"].ToString());
Debug.Log(values["nickname"].ToString());
Debug.Log(values["linkedID"].ToString());
Debug.Log(values["linkedType"].ToString());
Debug.Log(values["country"].ToString());
Debug.Log(values["purchaseCount"].ToString());
Debug.Log(values["purchaseTotalPrice"].ToString());
Debug.Log(values["purchaseCurrencyCode"].ToString());
Debug.Log(values["purchaseVoidedCount"].ToString());
Debug.Log(values["purchaseVoidedTotalPrice"].ToString());
Debug.Log(values["purchaseVoidedCurrencyCode"].ToString());
Debug.Log(values["country"].ToString());
Debug.Log(values["timezone"].ToString());
Debug.Log(values["offset"].ToString());
Debug.Log(values["joinPeriod"].ToString());
}
else
{
if (values != null)
{
if (values["ErrorCode"].ToString() == "30007")
{
Debug.Log(values["WithdrawalKey"].ToString());
}
else if (values["ErrorCode"].ToString() == "70002")
{
Debug.Log(values["BlockKey"].ToString());
}
else
{
Debug.Log("Fail");
}
}
else
{
Debug.Log("Fail");
}
}
});
}
}
调用方法
调用 Sign_in_with_Google() 后,会通过 Web 访问弹出 Google 账号选择窗口。
选择账号完成认证后,将自动返回手机。
通过 SendTokenToServer(string token) 传递 token 值。
使用该 token 值进行 Google 账号关联的账号注册(SocialSignIn)或会员转换(SocialChange)。
- 如果是游客关联后转换为 Google 账号,则进行会员转换
- 如果从一开始就直接进行 Google 登录,则进行账号注册
各平台回调处理
Android
- 通过 DeepLink 方式接收回调。
- 在
Application.deepLinkActivated事件中注册回调方法。 - 如果包含 Chrome Custom Tabs 库,浏览器将以应用内叠加形式打开。
- 如果没有该库,则使用外部 Chrome 浏览器打开,认证完成后通过深度链接返回应用。
iOS
- 使用 ASWebAuthenticationSession 在应用内打开认证会话。
- 通过
SetGoogleAuthCallback注册回调,认证完成时会被调用。
void Start()
{
Plugin plugin = Plugin.GetInstance();
// iOS Google OAuth 콜백 등록
plugin.SetGoogleAuthCallback((result) =>
{
if (result.StartsWith("error:"))
{
Debug.LogError("[GoogleOAuth] iOS Auth Error: " + result);
return;
}
// result는 콜백 URL 전체 (예: {game_id}://#id_token=xxx&...)
// ※ mygame:// scheme은 deprecated 되었습니다. PlayNANOO 콘솔에 등록된 Game ID를 scheme으로 사용합니다.
string token = ExtractIdToken(result);
if (!string.IsNullOrEmpty(token))
{
// 토큰으로 SocialSignIn 또는 SocialChange 호출
}
});
}
private string ExtractIdToken(string url)
{
if (!url.Contains("#")) return null;
string fragment = url.Split('#')[1];
string[] parts = fragment.Split('&');
foreach (var p in parts)
{
if (p.StartsWith("id_token="))
return p.Substring("id_token=".Length);
}
return null;
}
通信结果
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"Token" : {
"AccessToken" : "String",
"RefreshToken" : "String"
},
"Player" : {
"UserUniqueID" : "String",
"OpenID" : "String",
"Nickname" : "String",
"LinkedID" : "String",
"LinkedType" : "String",
"PurchaseCount" : "Integer",
"PurchaseTotalPrice" : "Double",
"PurchaseCurrencyCode" : "String",
"PurchaseVoidedCount" : "Integer",
"PurchaseVoidedTotalPrice" : "Double",
"PurchaseVoidedCurrencyCode" : "String",
"Country" : "String",
"Timezone" : "String",
"Offset" : "Integer",
"JoinPeriod" : "Integer"
}
}
通信结果详细信息
| 数据键 | 说明 | 类型 |
|---|---|---|
| Token.AccessToken | 玩家访问令牌 | string |
| Token.RefreshToken | 玩家刷新令牌 | string |
| Player.UserUniqueID | 玩家唯一识别 ID | string |
| Player.OpenID | 玩家唯一识别 Open ID | string |
| Player.Nickname | 玩家昵称 | string |
| Player.LinkedID | 玩家关联识别 ID | string |
| Player.LinkedType | 玩家关联类型 | string |
| Player.PurchaseCount | 玩家支付次数 | integer |
| Player.PurchaseTotalPrice | 玩家支付累计金额 | double |
| Player.PurchaseCurrencyCode | 玩家支付货币 | string |
| Player.PurchaseVoidedCount | 玩家退款次数 | integer |
| Player.PurchaseVoidedTotalPrice | 玩家退款累计金额 | double |
| Player.PurchaseVoidedCurrencyCode | 玩家退款货币 | string |
| Player.Country | 玩家国家代码 | string |
| Player.Timezone | 玩家国家时区 | string |
| Player.Offset | 玩家时区时差(基于 UTC) | integer |
| Player.JoinPeriod | 玩家注册时长 | integer |
| WithdrawalKey | 注销账号查询密钥 | string |
错误信息
玩家信息不存在时。 ErrorCode : 30000 ErrorMessage : NotFoundAccountException
玩家信息在其他设备上使用中时 ErrorCode : 30006 ErrorMessage : DuplicatedDeviceException
玩家已申请注销时 ErrorCode : 30007 ErrorMessage : WithDrawalException