게임을 만듭니다.

구글 플레이 게임 서비스를 통한 인증 및 검증 본문

unclassfied

구글 플레이 게임 서비스를 통한 인증 및 검증

인카고 인카고 2016.01.27 13:32
주의 : 아래 설명한 내용은 구글 플레이 게임 서비스를 통한 인증 및 검증에 대한 Best Practice를 제공하지 않을 가능성을 가지고 있습니다. 또한 번역에 있어서 미흡한 부분이 있을 수 있으니 참고로 추가해놓은 링크를 적극활용하시기 바랍니다.


유니티 프로젝트와 구글 플레이 게임 서비스(이하 GPGS) 인증 방법은 구글에서 제공하는 플러그인의 설명에 충분히 설명되어 있으므로 해당 내용은 생략합니다.


결국 알고 싶은것은 GPGS 인증을 거친 유저를 게임서버(backend)에서 어떻게 검증하고 어떤 정보를 Key로 하여 데이터베이스에 관련 레코드들을 생성 및 조회할것이냐 입니다.

유니티에서 GPGS 인증과 관련된 코드는 다음과 같을것입니다.


Social.localUser.Authenticate((bool success) =>
        {
            mAuthenticating = false;
            if (success)
            {
                // if we signed in successfully, load data from cloud
                Debug.Log("Login successful!");
                Debug.Log("Local user's username is " + ((PlayGamesLocalUser)Social.localUser).userName);
                Debug.Log("Local user's id is " + ((PlayGamesLocalUser)Social.localUser).id);

                StartCoroutine(GetIdToken());
            }
            else
            {
                // no need to show error message (error messages are shown automatically
                // by plugin)
                Debug.LogWarning("Failed to sign in with Google Play Games.");
            }
        });


 IEnumerator GetIdToken()
    {
        while (String.IsNullOrEmpty(((PlayGamesLocalUser)Social.localUser).idToken))
            yield return null;

        Debug.Log("Local user's idToken is " + ((PlayGamesLocalUser)Social.localUser).idToken);
        string idToken = ((PlayGamesLocalUser)Social.localUser).idToken;
        string validationUrl = "http://192.168.0.108:3000/verify/"+idToken;

        StartCoroutine(VerifyIdToken(validationUrl));
    }

public IEnumerator VerifyIdToken(string validationUrl)
    {
        WWW www = WWWUtils.Instance.GET(validationUrl);

        while (!www.isDone) { yield return null; }
        if (!www.isDone || !string.IsNullOrEmpty(www.error))
        {
            Debug.LogError("Load Failed");
            yield break;
        }

        Debug.Log("Verify Result");
        Debug.Log(www.text.Trim());
    }

여기서 주의할점은 GPGS 인증을 거친 사용자의 idToken을 인증 성공 시점에 PlayGamesPlatform.Instance.GetIdToken() 을 통해 불러오면 빈 값이 나온다는 것입니다.
따라서 별도의 코루틴을 통해 idToken을 알아냅니다. 이 idToken을 게임회사가 운영하는 backend서버에서 검증해야 할 것입니다.
저는 Node.js를 이용하여 로컬환경에 간단한 서버를 만들었습니다.

app.get('/verify/:idToken', function (req, res){
  console.log("verify : " + req.params.idToken);
  var option = {
    host: 'www.googleapis.com',
    path: '/oauth2/v3/tokeninfo?id_token=' + req.params.idToken
  }
  https.get(option, function(resp){
    resp.on('data', function(chunk){
      console.log(JSON.parse(chunk));
      //res.json(JSON.parse(chunk));
    });
  });
});

게임클라이언트로부터 받은 idToken을 구글의 tokeninfo 엔드포인트를 사용하여 검증합니다.

위 코드에서 chunk부분을 JSON으로 파싱하고 나면 다음과 같은 오브젝트(페이로드)를 얻게 됩니다.

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

확인할 부분은 aud입니다. 이 aud가 플레이콘솔에서 확인할 수 있는 자신의 어플리케이션 클라이언트아이디와 같은지 확인합니다.
(부가적으로 azp도 확인할 수 있습니다. 구글 플레이 콘솔에서 연결된 앱의 클라이언트을 확인해보세요.)

이를 통해서

  1. 토큰이 구글을 통해 발행됬음을 확인할 수 있습니다.
  2. 토큰 발행을 요청한사람이 페이로드의 email필드에 해당하는 사람이란 것을 확인할 수 있습니다.
  3. 토큰 발행은 페이로드의 aud를 클라이언트아이디로 가진 어플리케이션을 통해 이루어졌음을 확인할 수 있습니다.
(위 3가지 항목에 대한 정확한 사항은 http://android-developers.blogspot.kr/2013/01/verifying-back-end-calls-from-android.html 를 확인해주세요. 저의 번역은 후집니다.)

이제 GPGS 인증을 한 사람이 누구인지 알게되었으니 다음 프로세스(백엔드에서의 세션 생성/회원가입/로그인)를 진행하면됩니다.
회원생성(가입)시에는 페이로드의 sub를 키로 생성하면 됩니다. 페이로드의 sub는 구글아이디(이메일 말고 아이디)와 동일합니다.


4 Comments
댓글쓰기 폼