[Из песочницы] Unity3d / Android: проверка пользователя на собственном сервере Node.JS

Для реализации проверки пользователя вашего android приложения, созданного в unity3d, на своем node.js сервере, вам понадобится:

— Приложение в GooglePlay (опубликованное даже в режиме альфа-тестирования)
 — Плагин GooglePlayGames for Unity3D
 — Доступ в консоль Google Cloud
 — Ваш Node.JS-сервер
 — Модуль GoogleApis для node.js: npm install googleapis --save

Если ваше приложение еще в режиме альфа/бета-версии в GooglePlay — не забудьте добавить в список тестировщиков аккаунт, с помощью которого собираетесь тестировать. Также ваше приложение должно быть подключено в Игровых Сервисах.

image

Клиент


Распаковываем в unity3d плагин GooglePlayForUnity3d. Открываем Window/ GooglePlayGames/Setup/Android Setup.

Первые два поля можно оставить без изменений. Для информации по Resources Definition — идем в консоль GooglePlay, раздел Игровые сервисы, Достижения. Вводим минимум 5 достижений (если их нет) и находим ссылку «Получить ресурсы». Нажимаем, открываем раздел Android и копируем все в Unity3d в поле Resources Definition.

image

Включаем GooglePlus API. В поле Web App Client Id вводим идентификатор вида ХХХХХХ.apps.googleusercontent.com, его можно получить в консоли GoogleCloud (будет описано ниже).

image

Нажимаем Setup. Если последует запросы на изменение версий файлов с 10.0.1 на 10.2.0 — лучше отказаться и выбрать «Keep».

Небольшое отступление — если у вас в папке Plugins/Android есть файлы sdk (*.aar) версии выше 10.0.1 — замените их на версию 10.0.1 — найти их можно в установленной у вас sdk (sdk\extras\google\m2repository\com\google\android\gms\) — это временный шаг — только с данной версией.

Далее добавляем в клиенте GoogleAuth.cs который будет получать серверный токен.

GoogleAuth.cs
using System;
using System.Collections;
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using UnityEngine;

public class GoogleAuth:MonoBehaviour
{
    /// 
    /// Возвращает серверный токен для проверки на сервере
    /// 
    /// 
    public void Auth(Action callback)
    {
        InitAuth(() =>
        {
            GetServerToken(callback);
        });
    }

    private void InitAuth(Action callback)
    {
        var config = new PlayGamesClientConfiguration.Builder()
        .AddOauthScope("profile")
        .AddOauthScope("email")
        .Build();
        PlayGamesPlatform.InitializeInstance(config);
        PlayGamesPlatform.Activate();
        Social.localUser.Authenticate((success, str) =>
        {
            if (success)
                callback();
            else
                Debug.Log("Error on Social Authenticate: " + str);
        });
    }

    private void GetServerToken(Action callback)
    {
        StartCoroutine(ReadToken((serverToken,empty) =>
        {
            callback(serverToken);
        }));
    }

    private IEnumerator ReadToken(Action callback)
    {
        yield return null;
        if (!PlayGamesPlatform.Instance.IsAuthenticated()) //Проверка текущего состояния
        {
            PlayGamesPlatform.Instance.Authenticate((result, msg) => //аутентификация без показа уведомлений игроку
            {
                if (!result)
                {
                    PlayGamesPlatform.Instance.Authenticate(
                        (result2, msg2) => //аутентификация с показом окна googleplay игроку
                        {
                            if (!result2)
                            {
                                PlayGamesPlatform.Instance.GetIdToken(
                                    val => //пробуем получить IdToken и перезапускаем авторизацию
                                    {
                                        StartCoroutine(ReadToken(callback));
                                    });
                            }
                        }, false);
                }
            }, true);
        }
        else
        {
                PlayGamesPlatform.Instance.GetServerAuthCode(
                    (status, code) => //получаем токен для проверки на своем сервере
                    {
                        if (status != CommonStatusCodes.Success || string.IsNullOrEmpty(code))
                            StartCoroutine(ReadToken(callback));
                        else
                            callback(code, null);
                    });
            
        }
    }
}


Прикрепляем его на сцене к какому-либо GameObject.

Для получения серверного токена необходимо вызвать метод Auth с обратным вызовом в котором и будет серверный токен. Места возникновения ошибок вы можете видеть в классе GoogleAuth — можете либо выводить сообщения пользователям, либо отправлять статистику и т.п.

В AndroidManifest.xml добавляем:


  
  
  

Сервер


Необходим файл содержащий идентификационные данные вашего сервера для GooglePlay. Открываем консоль Cloud Google (https://console.cloud.google.com/apis/credentials? project=ид_вашего_проекта).

Находим в разделе Идентификаторы клиентов OAuth 2.0 идентификатор с типом «Веб-приложение». Открываем идентификатор и скачиваем client-secret (файл, который заканчивается apps.googleusercontent.com.json):

image

Сохраняем в папку с серверным приложением. Указанный в том же окне идентификатор клиента копируем и вставляем в клиентскую часть (Unity3d) в окне GooglePlayGames — Android configuration в поле «Web App Client id» которое раньше оставляли не заполненным.

Как вы будете доставлять необходимые данные из вашего приложения на ваш сервер не столь важно, тут на ваш выбор (в т.ч. express, websocket, socket.io и т.д.).

Создаем класс, который будет проверять полученный от приложения токен:

GooglePlayAuth.js
"use strict";
const fs = require('fs');
const https = require("https");
const google = require('googleapis');

/**
 * Путь к файлу полученному в консоли GoogleCloud
 */
const _clientSecret = "client_secret.apps.googleusercontent.com.json";
const _userInfoUrl = "https://www.googleapis.com/games/v1/players/me";

let oauth2Client;

/**
 * 
 */
class GooglePlayAuth {
    /**
     * Единоразовая инициализация
     * @param callback
     */
    static Init(callback) {
        fs.readFile(_clientSecret, function (err, content) {
            if (err) {
                callback(err);
                return;
            }
            const credentials = JSON.parse(content);
            oauth2Client = new google.auth.OAuth2(credentials.web.client_id, credentials.web.client_secret, credentials.web.redirect_uris[0]);
            callback(null);
        });
    }
    /**
     * Проверка пользователя 
     * @param serverToken
     * @param callback
     */
    static Verify(serverToken,callback) {
        oauth2Client.getToken(serverToken, function (err, token) {
            if (err) {
                callback(`Error while retrieve access token: ${err}`);
                return;
            }
            oauth2Client.credentials = token;
            //Получение информации о пользователе
            require("https").get(`${_userInfoUrl}?access_token=${token.access_token}`, function (res) {
                res.on("data", function (d) {
                    let userData = {};
                    try {
                        userData = JSON.parse(d);
                    } catch (er) {
                        callback(`Error parse user data ${er}`);
                        return;
                    }
                    if (userData.playerId == null) {
                        callback(`Error read playerId: ${userData}`);
                        return;
                    }
                    //все в порядке - возвращаем данные пользователя в модуль подключения
                    callback(null, userData);
                });
            }).on("error", function (err) {
                callback(`Fail request: ${err}`);
            });
        });
    }
}

module.exports = GooglePlayAuth;


При запуске сервера не забудьте вызвать GooglePlayAuth.Init.

Полученный от клиентского приложения серверный токен отправляем в GooglePlayAuth.Verify, который вернет в обратном вызове либо ошибку, либо данные пользователя, полученные от сервиса Google.

Спасибо за внимание!

Комментарии (0)

© Habrahabr.ru