Для реализации проверки пользователя вашего android приложения, созданного в unity3d, на своем node.js сервере, вам понадобится:
— Приложение в GooglePlay (опубликованное даже в режиме альфа-тестирования)
— Плагин GooglePlayGames for Unity3D
— Доступ в консоль Google Cloud
— Ваш Node.JS-сервер
— Модуль GoogleApis для node.js: npm install googleapis --save
Если ваше приложение еще в режиме альфа/бета-версии в GooglePlay — не забудьте добавить в список тестировщиков аккаунт, с помощью которого собираетесь тестировать. Также ваше приложение должно быть подключено в Игровых Сервисах.
Клиент
Распаковываем в unity3d плагин GooglePlayForUnity3d. Открываем Window/ GooglePlayGames/Setup/Android Setup.
Первые два поля можно оставить без изменений. Для информации по Resources Definition — идем в консоль GooglePlay, раздел Игровые сервисы, Достижения. Вводим минимум 5 достижений (если их нет) и находим ссылку “Получить ресурсы”. Нажимаем, открываем раздел Android и копируем все в Unity3d в поле Resources Definition.
Включаем GooglePlus API. В поле Web App Client Id вводим идентификатор вида ХХХХХХ.apps.googleusercontent.com, его можно получить в консоли GoogleCloud (будет описано ниже).
Нажимаем Setup. Если последует запросы на изменение версий файлов с 10.0.1 на 10.2.0 — лучше отказаться и выбрать “Keep”.
Небольшое отступление — если у вас в папке Plugins/Android есть файлы sdk (*.aar) версии выше 10.0.1 — замените их на версию 10.0.1 — найти их можно в установленной у вас sdk (sdkextrasgooglem2repositorycomgoogleandroidgms) — это временный шаг — только с данной версией.
Далее добавляем в клиенте 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):
Сохраняем в папку с серверным приложением. Указанный в том же окне идентификатор клиента копируем и вставляем в клиентскую часть (Unity3d) в окне GooglePlayGames — Android configuration в поле «Web App Client id» которое раньше оставляли не заполненным.
Как вы будете доставлять необходимые данные из вашего приложения на ваш сервер не столь важно, тут на ваш выбор ( в т.ч. express, websocket, socket.io и т.д.).
Создаем класс, который будет проверять полученный от приложения токен:
"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.
Спасибо за внимание!
Автор: McRain