跳转到主要内容

Sign in with Google

基于 OAuth 2.0 的 Google 登录网页认证方式。支持 iOS、Android 通用。

工作方式

Android:

  1. 在外部浏览器(或 Chrome Custom Tabs)中选择 Google 账户
  2. 通过 Deep Link 接收 id_token
  3. 使用令牌调用账户注册(SocialSignIn)或会员转换(SocialChange)API

iOS:

  1. 通过 ASWebAuthenticationSession 显示应用内认证会话
  2. 通过 OnGoogleAuthCallback 方法接收 id_token
  3. 使用令牌调用账户注册(SocialSignIn)或会员转换(SocialChange)API

Unity 实现

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class GoogleSignin : MonoBehaviour
{
private string HOST_PLAYNANOO_OAUTH2REDIRECT = "https://www.playnanoo.com/oauth2redirect.html";
private string OAUTH2REDIRECT_SCOPE = "openid email profile";
private string clientId = "Your Google Client Id";

void Start()
{
Application.deepLinkActivated += OnDeepLink;
}

private void OnDeepLink(string url)
{
string token = ExtractIdToken(url);
if (!string.IsNullOrEmpty(token))
{
SendTokenToServer(token);
}
}

private string ExtractIdToken(string url)
{
// query parameter(?) 또는 fragment(#)에서 id_token 추출
string paramString = null;

if (url.Contains("?"))
{
paramString = url.Split('?')[1];
}
else if (url.Contains("#"))
{
paramString = url.Split('#')[1];
}

if (string.IsNullOrEmpty(paramString)) return null;

string[] parts = paramString.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()
{
string nonce = Guid.NewGuid().ToString("N");

string authUrl = "https://accounts.google.com/o/oauth2/v2/auth"
+ "?client_id=" + clientId
+ "&redirect_uri=" + HOST_PLAYNANOO_OAUTH2REDIRECT
+ "&response_type=id_token"
+ "&scope=" + Uri.EscapeDataString(OAUTH2REDIRECT_SCOPE)
+ "&nonce=" + nonce
+ "&prompt=select_account"
+ "&login_hint="; // 빈 값으로 자동 로그인 방지

// 외부 브��우저에서 열기 (403 disallowed_useragent 방지)
OpenURLInExternalBrowser(authUrl);
}

private void OpenURLInExternalBrowser(string url)
{
if (Application.platform == RuntimePlatform.Android)
{
try
{
using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
using (AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
using (AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", "android.intent.action.VIEW"))
using (AndroidJavaClass uri = new AndroidJavaClass("android.net.Uri"))
{
intent.Call<AndroidJavaObject>("setData", uri.CallStatic<AndroidJavaObject>("parse", url));
intent.Call<AndroidJavaObject>("addFlags", 0x10000000); // FLAG_ACTIVITY_NEW_TASK
intent.Call<AndroidJavaObject>("addCategory", "android.intent.category.BROWSABLE");

try
{
intent.Call<AndroidJavaObject>("setPackage", "com.android.chrome");
currentActivity.Call("startActivity", intent);
}
catch
{
intent.Call<AndroidJavaObject>("setPackage", null);
currentActivity.Call("startActivity", intent);
}
}
}
catch
{
Application.OpenURL(url);
}
}
else
{
Application.OpenURL(url);
}
}

//인증 완료 시 토큰 받는 메소드.
private void SendTokenToServer(string token)
{
//toten 값으로 SocialChange 또는 SocialSignIn 진행.
//SocialChange(token, PN_ACCOUNT_GOOGLE);
// or
//SocialSignIn(token, PN_ACCOUNT_GOOGLE);
}

//계정 전환 예시. SocialChange
public void SocialChange(string token, string accountType)
{
}

public void SocialSignIn(string token, string accountType)
{
}
}

OAuth 2.0 参数

参数说明
client_id在 Google Cloud Console 中获取OAuth 网页客户端 ID
redirect_urihttps://www.playnanoo.com/oauth2redirect.html认证后重定向 URL
response_typeid_token请求 OpenID Connect ID 令牌
scopeopenid email profile请求的用户信息范围
nonceGuid.NewGuid()防止重放攻击的随机字符串
promptselect_account强制显示账户选择
环境设置必需

使用 Sign in with Google 之前,请参考 Google 环境设置 文档完成以下设置:

  • 在 Google Cloud Console 中获取 OAuth 2.0 客户端 ID
  • Android/iOS Deep Link 设置
  • 重定向 URI 注册

使用方法

1. 开始 Google 登录

Sign_in_with_Google();

打开外部浏览器,用户选择 Google 账户。

2. 使用令牌进行账户关联

认证完成后,使用 SendTokenToServer 方法中获取的 id_token 调用 PlayNANOO API:

新登录(SocialSignIn)

public void SocialSignIn(string token, string accountType)
{
// Google 账户首次登录
//accountType : PN_ACCOUNT_GOOGLE
}

会员转换(SocialChange)

public void SocialChange(string token, string accountType)
{
// 从游客转换为 Google 会员
//accountType : PN_ACCOUNT_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;
}