Unity 和 Google OAuth2 授权代码流程
Unity and Google OAuth2 Authorization Code Flow
我正在尝试构建要使用 WebGL 部署的 Unity 应用程序。我正在尝试将 Google 登录合并到应用程序中,到目前为止,这是我在 Chrome:
中构建的 Unity WebGL 中成功实现的
- 用户在 Unity 应用程序的选项卡 A 中按下“使用 Google 登录”按钮。
- 用户被定向到另一个选项卡 B 上的 Google 登录页面。
- 用户使用 Google 帐户登录,并被重定向到我的
redirect_uri
,它只是 https://localhost
,带有 auth
代码参数。
我的问题是,我是否可以使用 .jslib
个文件执行以下操作:
- 不是转到选项卡 B 上的
redirect_uri
,而是返回选项卡 A 而不是重新加载,传递 auth
代码。
- 在上面一行的基础上,有 javascript 个处理程序,即:
- 收到授权码后,按照指示here.
发起请求为id_token交换授权码
- 收到 id_token 后,调用 C# 脚本函数对 id_token 执行进一步的操作。
或者,我可以将 redirect_uri
设置为我的后端服务器上的端点,并使用 Google 客户端 SDK 执行身份验证令牌 -> id_token 流程。但是,对于这种方法,我想知道我是否能够
- 在后端服务器完成auth token -> id_token流程后,关闭当前window,Tab B,返回Tab A。
- 回到 Tab A 后,将 Unity 重定向到特定场景(不再是登录场景,而是用户通过身份验证后被定向到的主页)。
非常感谢我能得到的任何帮助:')
编辑:为了更清楚起见,我想要实现的是 FacebookSDK for Unity 在他们的 FB.LogInWithReadPermissions()
中所做的事情。整个授权代码 -> access_token 流程是无缝的,最后我被重定向回选项卡 A 中的 Unity 应用程序 access_token.
我设法找到了 Javascript 解决方案来实现我的第一个方法。区别是因为
- 我的应用程序永远不会投入生产
- 与我的 Facebook OAuth 实现一致,
我使用了隐式流程而不是授权代码流程,尽管出于安全考虑,这不是推荐的方式。但是,我认为您可以轻松地使用授权代码流程,检索授权代码并将其传递到您的后端以交换 ID 令牌。 (据我所知,您不能使用 Javascript/XHR 请求进行此交换)
因此,流程是从我的 C# 脚本中调用 .jslib
文件中的 Javascript 函数。基本上,该函数检测 OAuth window 何时重定向回我的 redirect_uri
,然后从重定向的 URI 获取 access_token
参数,并调用 C# 脚本函数。从那里,您应该能够做任何您需要做的事情(改变场景、发送到您的后端等)。请注意,这里有一个 try/catch,因为如果您尝试从 Google 登录页面获取信息,将会出现错误。
文件如下:
mergeInto(LibraryManager.library, {
OpenOAuthInExternalTab: function (url, callback) {
var urlString = Pointer_stringify(url);
var callbackString = Pointer_stringify(callback);
var child = window.open(urlString, "_blank");
var interval = setInterval(function() {
try {
// When redirected back to redirect_uri
if (child.location.hostname === location.hostname) {
clearInterval(interval) // Stop Interval
// // Auth Code Flow -- Not used due to relative complexity
// const urlParams = new URLSearchParams(child.location.search);
// const authCode = urlParams.get('code');
// console.log("Auth Code: " + authCode.toString());
// console.log("Callback: " + callbackString);
// window.unityInstance.SendMessage('Auth', callbackString, authCode);
// Implicit Flow
var fragmentString = child.location.hash.substr(1);
var fragment = {};
var fragmentItemStrings = fragmentString.split('&');
for (var i in fragmentItemStrings) {
var fragmentItem = fragmentItemStrings[i].split('=');
if (fragmentItem.length !== 2) {
continue;
}
fragment[fragmentItem[0]] = fragmentItem[1];
}
var accessToken = fragment['access_token'] || '';
console.log("access_token: " + accessToken);
child.close();
// Invoke callback function
window.unityInstance.SendMessage('Auth', callbackString, accessToken);l
}
}
catch(e) {
// Child window in another domain
console.log("Still logging in ...");
}
}, 50);
}
});
然后,在我的 C# 脚本中,我使用以下代码调用此函数:
public class GoogleHelper : MonoBehaviour
{
[DllImport("__Internal")]
private static extern void OpenOAuthInExternalTab(string url, string callbackFunctionName);
// ...
public void Login(string callbackFunctionName) {
var redirectUri = "https://localhost";
var url = "https://accounts.google.com/o/oauth2/v2/auth"
+ $"?client_id={clientId}"
+ "&response_type=token"
+ "&scope=openid%20email%20profile"
+ $"&redirect_uri={redirectUri}";
OpenOAuthInExternalTab(url, callbackFunctionName);
}
// ...
}
当然,这太hacky了,我对Javascript不是很熟悉,所以真的不知道上面代码的含义,但它适用于我的用例。
我正在尝试构建要使用 WebGL 部署的 Unity 应用程序。我正在尝试将 Google 登录合并到应用程序中,到目前为止,这是我在 Chrome:
中构建的 Unity WebGL 中成功实现的- 用户在 Unity 应用程序的选项卡 A 中按下“使用 Google 登录”按钮。
- 用户被定向到另一个选项卡 B 上的 Google 登录页面。
- 用户使用 Google 帐户登录,并被重定向到我的
redirect_uri
,它只是https://localhost
,带有auth
代码参数。
我的问题是,我是否可以使用 .jslib
个文件执行以下操作:
- 不是转到选项卡 B 上的
redirect_uri
,而是返回选项卡 A 而不是重新加载,传递auth
代码。 - 在上面一行的基础上,有 javascript 个处理程序,即:
- 收到授权码后,按照指示here. 发起请求为id_token交换授权码
- 收到 id_token 后,调用 C# 脚本函数对 id_token 执行进一步的操作。
或者,我可以将 redirect_uri
设置为我的后端服务器上的端点,并使用 Google 客户端 SDK 执行身份验证令牌 -> id_token 流程。但是,对于这种方法,我想知道我是否能够
- 在后端服务器完成auth token -> id_token流程后,关闭当前window,Tab B,返回Tab A。
- 回到 Tab A 后,将 Unity 重定向到特定场景(不再是登录场景,而是用户通过身份验证后被定向到的主页)。
非常感谢我能得到的任何帮助:')
编辑:为了更清楚起见,我想要实现的是 FacebookSDK for Unity 在他们的 FB.LogInWithReadPermissions()
中所做的事情。整个授权代码 -> access_token 流程是无缝的,最后我被重定向回选项卡 A 中的 Unity 应用程序 access_token.
我设法找到了 Javascript 解决方案来实现我的第一个方法。区别是因为
- 我的应用程序永远不会投入生产
- 与我的 Facebook OAuth 实现一致,
我使用了隐式流程而不是授权代码流程,尽管出于安全考虑,这不是推荐的方式。但是,我认为您可以轻松地使用授权代码流程,检索授权代码并将其传递到您的后端以交换 ID 令牌。 (据我所知,您不能使用 Javascript/XHR 请求进行此交换)
因此,流程是从我的 C# 脚本中调用 .jslib
文件中的 Javascript 函数。基本上,该函数检测 OAuth window 何时重定向回我的 redirect_uri
,然后从重定向的 URI 获取 access_token
参数,并调用 C# 脚本函数。从那里,您应该能够做任何您需要做的事情(改变场景、发送到您的后端等)。请注意,这里有一个 try/catch,因为如果您尝试从 Google 登录页面获取信息,将会出现错误。
文件如下:
mergeInto(LibraryManager.library, {
OpenOAuthInExternalTab: function (url, callback) {
var urlString = Pointer_stringify(url);
var callbackString = Pointer_stringify(callback);
var child = window.open(urlString, "_blank");
var interval = setInterval(function() {
try {
// When redirected back to redirect_uri
if (child.location.hostname === location.hostname) {
clearInterval(interval) // Stop Interval
// // Auth Code Flow -- Not used due to relative complexity
// const urlParams = new URLSearchParams(child.location.search);
// const authCode = urlParams.get('code');
// console.log("Auth Code: " + authCode.toString());
// console.log("Callback: " + callbackString);
// window.unityInstance.SendMessage('Auth', callbackString, authCode);
// Implicit Flow
var fragmentString = child.location.hash.substr(1);
var fragment = {};
var fragmentItemStrings = fragmentString.split('&');
for (var i in fragmentItemStrings) {
var fragmentItem = fragmentItemStrings[i].split('=');
if (fragmentItem.length !== 2) {
continue;
}
fragment[fragmentItem[0]] = fragmentItem[1];
}
var accessToken = fragment['access_token'] || '';
console.log("access_token: " + accessToken);
child.close();
// Invoke callback function
window.unityInstance.SendMessage('Auth', callbackString, accessToken);l
}
}
catch(e) {
// Child window in another domain
console.log("Still logging in ...");
}
}, 50);
}
});
然后,在我的 C# 脚本中,我使用以下代码调用此函数:
public class GoogleHelper : MonoBehaviour
{
[DllImport("__Internal")]
private static extern void OpenOAuthInExternalTab(string url, string callbackFunctionName);
// ...
public void Login(string callbackFunctionName) {
var redirectUri = "https://localhost";
var url = "https://accounts.google.com/o/oauth2/v2/auth"
+ $"?client_id={clientId}"
+ "&response_type=token"
+ "&scope=openid%20email%20profile"
+ $"&redirect_uri={redirectUri}";
OpenOAuthInExternalTab(url, callbackFunctionName);
}
// ...
}
当然,这太hacky了,我对Javascript不是很熟悉,所以真的不知道上面代码的含义,但它适用于我的用例。