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 {     /// <summary>     /// Возвращает серверный токен для проверки на сервере     /// </summary>     /// <param name="callback"></param>     public void Auth(Action<string> 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<string> callback)     {         StartCoroutine(ReadToken((serverToken,empty) =>         {             callback(serverToken);         }));     }      private IEnumerator ReadToken(Action<string, string> 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 добавляем:

<uses-permission android:name="android.permission.GET_ACCOUNTS"/>   <uses-permission android:name="android.permission.USE_CREDENTIALS"/>   <uses-permission android:name="android.permission.INTERNET"/>   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Сервер

Необходим файл содержащий идентификационные данные вашего сервера для 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.

Спасибо за внимание!
ссылка на оригинал статьи https://habrahabr.ru/post/325900/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *