- Unity Google play plugin으로 idToken 발급
- 서버에서 idToken 유효성 검사
2주전인가 했던 기능인데 생각해보니 블로그에 올린적이 없었던것 같아 올린다.
로그인 기능이 있는 게임 서버의 경우 해당 내용이 꽤나 중요하지 않을까 싶다.
Unity Google play plugin으로 idToken 발급
public void SignIn(Action<string> callback)
{
PlayGamesPlatform.DebugLogEnabled = true;
PlayGamesPlatform.Activate();
PlayGamesPlatform.Instance.Authenticate((status) =>
{
if (status == false)
{
callback.Invoke("failed");
return;
}
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
.AddOauthScope("profile")
.RequestIdToken()
.RequestServerAuthCode(false)
.RequestEmail()
.Build();
PlayGamesPlatform.InitializeInstance(config);
string name = PlayGamesPlatform.Instance.GetUserDisplayName();
string id = PlayGamesPlatform.Instance.GetUserId();
string ImgUrl = PlayGamesPlatform.Instance.GetUserImageUrl();
PlayGamesPlatform.Instance.Authenticate(SignInInteractivity.CanPromptOnce, (SignInStatus result) =>
{
if (result == SignInStatus.Success)
{
string idToken = PlayGamesPlatform.Instance.GetIdToken();
callback.Invoke("Success");
// JWT 토큰을 서버로 전송
// JWT 토큰을 FlatBuffer 패킷으로 만들어서 서버에 전송
FlatBufferBuilder builder = new FlatBufferBuilder(1);
var jwtOffset = builder.CreateString(idToken);
var data = PKT_C_Res_JWT.CreatePKT_C_Res_JWT(builder, jwtOffset);
var packet = GameManager.Packet.CreatePacketWithAES(data, builder, PKT_Type.PKT_C_Res_JWT, GameManager.Network.Session);
GameManager.Network.Send(packet);
Debug.Log("JWT token sent to server");
Debug.Log("Authentication Succeeded.");
}
else
{
callback.Invoke("failed");
Debug.Log("Authentication Failed. SignInStatus: " + result);
}
});
});
Unity에서 idToken을 발급하는 함수이다.
필자는 plugin 버전을 10으로 썻다.
이에 관련된 문서는 아래와 같다.
Unity에서 Google Play 게임 로그인으로 PlayFab 인증 - PlayFab
Unity에서 Google Play 게임 로그인을 사용한 PlayFab 인증의 예제를 안내합니다.
learn.microsoft.com
https://docs.unity.com/ugs/manual/authentication/manual/platform-signin-google
Attention: The following concerns products or services (each a “Third Party Product”) that are not developed, owned, or operated by Unity. This information might not be up-to-date or complete, and is provided to you for your information and convenience
docs.unity.com
현재 클라와 서버의 로그인 과정은 아래와 같다.
[Server의 token 요청]
↓
[Client token 응답]
↓
[Server의 token 유효성 검사 응답]
↓
[valid token인 경우 Client 로그인]
↓
[Client "Success" 출력]
이전에 RSA/AES로 패킷 암호화를 자동화하게 했기에
서버가 클라이언트의 암호화된 token을 받고 복호화한뒤 유효성 검사를 한다.
유효한 토큰인 경우 클라에서는 간단하게 화면 중앙 Text UI를 "Success"로 출력하게끔 만들었다.
서버에서 idToken 유효성 검사
public async Task VerifyJWT(string authCode, ClientSession clientSession)
{
FlatBufferBuilder builder = new FlatBufferBuilder(1);
bool success = false;
try
{
Console.WriteLine($"Received Auth Code: {authCode.Substring(0, Math.Min(20, authCode.Length))}...");
Console.WriteLine($"Auth Code length: {authCode.Length}");
// 직접 JWT 검증 (클라이언트에서 ID Token을 보냄)
Console.WriteLine("Validating JWT ID Token directly...");
var payLoad = await GoogleJsonWebSignature.ValidateAsync(authCode);
// 사용자 정보 저장
clientSession.ProfileURL = payLoad.Picture ?? "";
clientSession.UserId = payLoad.Subject;
clientSession.Email = payLoad.Email;
success = true;
Console.WriteLine($"JWT validation success for user: {payLoad.Subject}, Email: {payLoad.Email}");
Console.WriteLine($"Profile picture: {payLoad.Picture ?? "Not set"}");
// 로그인 성공 패킷 전송
var jwtOffset = builder.CreateString(authCode);
var userIdOffset = builder.CreateString(payLoad.Subject);
var emailOffset = builder.CreateString(payLoad.Email ?? "");
var profileUrlOffset = builder.CreateString(payLoad.Picture ?? "");
var displayNameOffset = builder.CreateString(payLoad.Name ?? payLoad.Email ?? "User");
var loginData = PKT_S_LoginSuccess.CreatePKT_S_LoginSuccess(builder,
jwtOffset, userIdOffset, emailOffset, profileUrlOffset, displayNameOffset);
var loginPkt = Manager.Packet.CreatePacketWithAES(loginData, builder, PKT_Type.PKT_S_LoginSuccess, clientSession);
clientSession.Send(loginPkt);
return;
}
catch (InvalidJwtException ex)
{
Console.WriteLine($"Invalid JWT token: {ex.Message}");
success = false;
}
catch (Exception ex)
{
Console.WriteLine($"JWT validation error: {ex.Message}");
Console.WriteLine($"Exception type: {ex.GetType().Name}");
success = false;
}
}
Unity Google Play Plugin은 IdToken을 string으로 가져온다.
그 token값을 그대로 유효성 검사 Google API에 넣어 호출하면 된다.
만약 유효하지 않은 Token이라면 exception을 반환한다.
이와 관련된 문서는 아래와 같다.
Class GoogleJsonWebSignature (1.69.0) | .NET client library | Google Cloud
Send feedback Class GoogleJsonWebSignature (1.69.0) Stay organized with collections Save and categorize content based on your preferences. Version latestkeyboard_arrow_down public class GoogleJsonWebSignature Inheritance object > GoogleJsonWebSignature Nam
cloud.google.com
비동기 함수이기에 await을 사용해서 호출하거나 Task로 관리해야한다.
저기서 유효한 Token이라고 반환한다면 그대로 Token에 담겨있는 Client의 Google 정보를 서버에 저장하고
Client에게 정보를 그대로 전달해주면 된다.
나중에 Client는 그 정보를 통해서 TextUI등 데이터 관리를 하게 된다.
'프로젝트 일기' 카테고리의 다른 글
모바일 온라인 오목 프로젝트 - 7 (0) | 2025.06.21 |
---|---|
모바일 온라인 오목 프로젝트 - 6 (0) | 2025.06.08 |
모바일 온라인 오목 프로젝트 - 5 (0) | 2025.05.10 |
모바일 온라인 오목 프로젝트 - 4 (0) | 2025.05.04 |
모바일 온라인 오목 프로젝트 - 3 (1) | 2025.05.01 |