问题描述
我正在Unity中开发一款手机游戏,并将Firebase Realtime数据库用于在线排行榜.
I'm working on a mobile game in Unity and using a Firebase Realtime Database for online leaderboards.
玩我的游戏的先决条件是用户登录Google Play服务(已使用官方SDK集成到Unity),因此我希望我的代码使用用户的Google Play服务帐户向我的数据库进行身份验证.
A pre-requisite for playing my game is the user logging into Google Play Services (Integrated into Unity using the official SDK), so I want my code to use the user's Google Play Services account to authenticate with my DB.
我知道可以通过Google Play服务进行身份验证,但是我的问题是:
I know that authentication via Google Play Services is possible, but my questions are:
- 使用REST API时可以使用Google Play服务进行身份验证吗?如果是这样,这种查询的结构是什么?
- 我需要在Firebase实时数据库侧设置哪些规则/配置,以允许来自经过身份验证的用户的所有读/写操作,并拒绝所有匿名操作?
提前谢谢!
推荐答案
我终于找到了答案,部分要感谢 PatrickMatrin 的回应.
I finally found the answer, thanks in part to Patrick Matrin's response.
答案是肯定的,是可能的,但这并不简单.
The answer is yes, it is possible, but it's not straightforward.
为了向请求添加身份验证,需要访问令牌.语法更改非常简单,所以假设您最初发布到的URL是:
In order to add authentication to requests, an access token is required.The syntax change is quite simple, so let's say the URL you were originally posting to was:
https://< DATABASE_NAME> .firebaseio.com/< SUB_FOLDER>/< SUB_FOLDER2> .json
您将希望将其更改为:
https://< DATABASE_NAME> .firebaseio.com/< SUB_FOLDER>/< SUB_FOLDER2> .json?access_token =< ACCESS_TOKEN>
您可以在此处了解更多信息.
You can read more about it here.
主要问题是获取访问令牌.要过度简化,您需要执行以下操作:
The main issue is getting that Access Token. To grossly over-simplify, what you want to do is the following:
- 在游戏中启动Google Play服务
- 使用Google Play服务对用户进行身份验证(让他们登录")
- 交换掉我们为访问令牌获得的身份验证代码
第1步和第2步应该非常简单,如果您使用的是Google Play服务,则可能已经完成了.无论如何,这就是该类在我的项目中的样子:
Steps 1 and 2 should be fairly straightforward, and you probably already did them if you're using Google Play Services. In any case, this is how the class looks in my project:
public class GPGSAuthentication : MonoBehaviour
{
public static PlayGamesPlatform platform;
void Start()
{
if (platform == null)
{
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder().RequestServerAuthCode(false).Build();
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.DebugLogEnabled = true;
platform = PlayGamesPlatform.Activate();
}
Social.Active.localUser.Authenticate(success =>
{
if (success)
{
Debug.Log("GSPS - Logged in successfully");
}
else
{
Debug.Log("GSPS - Falied to login");
}
});
}
}
请注意在配置版本中使用RequestServerAuthCode(false).如果要获取前面讨论的身份验证代码,则需要使用此代码.
Notice the use of RequestServerAuthCode(false) in the config build. You'll need this if you want to get the Authentication Code discussed earlier.
之后,您需要使用REST API才能将身份验证代码交换为访问令牌.您需要查询GoogleAPI URL并提供一些参数:
After that, you'll need to use REST API in order to exchange the auth code for an access token. You'll need to query a GoogleAPI URL and supply some parameters:
/// <summary>
/// Trades the auth code for a Google Access Token.
/// </summary>
/// <param name="clientID">The ID of the client we're trying to reach</param>
/// <param name="clientSecret">The secret of the client we're trying to reach</param>
/// <param name="grantType">The grant_type value</param>
/// <param name="authCode">The auth code we want to trade in for the Google Access Token</param>
/// <returns></returns>
IEnumerator GetAccessToken(string clientID, string clientSecret, string grantType, string authCode)
{
if (googleAccessToken != null && googleAccessToken != "")
{
Debug.Log("Not requesting googleAccessToken again since we already have it");
yield break;
}
//googleAccessToken = "";
WWWForm form = new WWWForm();
form.AddField("client_id", clientID);
form.AddField("client_secret", clientSecret);
form.AddField("grant_type", grantType);
form.AddField("code", authCode);
UnityWebRequest www = UnityWebRequest.Post("https://www.googleapis.com/oauth2/v4/token", form);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log("Ran into error while trying to get access token\n Error: " + www.error + "\nURL: " + www.url.ToString() + "\nCode: " + authCode);
}
else
{
Debug.Log("Got Access Token in return, full string is: \n" + www.downloadHandler.text);
GoogleData googleData = JsonUtility.FromJson<GoogleData>(www.downloadHandler.text);
googleAccessToken = googleData.access_token;
}
}
/// <summary>
/// Class for handling data received from Google after giving Auth Code
/// </summary>
[System.Serializable]
public class GoogleData
{
public string access_token;
public string token_type;
public int expires_in;
public string refresh_token;
}
您需要从创建的OAuth2网络客户端获取 client_id
和 client_secret
的值.您应该能够在Google API凭据页面中阅读它们.
You'll need to get the values for client_id
and client_secret
from your OAuth2 web client that you created. You should be able to read them in the Google API credentials page.
对于 grant_type
,始终提供值"authorization_code"
,并且为了获取身份验证码的值,请使用 PlayGamesPlatform.Instance.GetServerAuthCode()
,尽管显然只有在成功地在Google Play服务中登录用户之后.
As for grant_type
, always supply the value "authorization_code"
, and in order to get the value of your Authentication Code, use PlayGamesPlatform.Instance.GetServerAuthCode()
, though obviously only after successfully logging in the user in Google Play Services.
现在,您应该拥有使用Google Play服务通过Firebase对用户进行身份验证所需的一切.无需其他SDK或软件包/插件.
Now you should have everything needed to authenticate your user with Firebase using Google Play Services. No further SDK or package/plugin needed.
帕特里克在这里的答案是正确的.这是一条具有以下语法的简单规则:
Patrick's answer here was correct. This is a simple rule with the following syntax:
{
"rules": {
"node_to_protect": {
".read": "auth != null",
".write": "auth != null",
}
}
}
这篇关于使用Realtime Database的API时如何向Google Play服务进行身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!