我正在尝试构建一个Unity应用程序与WebGL部署。我正试图将谷歌登录纳入应用程序,到目前为止,这是我在Chrome中构建的Unity WebGL中所做的工作:
- 用户按"Login with google";按钮,在Unity应用程序,在选项卡a
- 用户被引导到另一个标签b上的Google Sign In页面。
- 用户用Google帐户登录,并被重定向到我的
redirect_uri
,这是简单的https://localhost
,auth
代码参数
我的问题是,我是否有可能使用.jslib
文件执行以下操作:
- 不去Tab B上的
redirect_uri
,而是回到Tab A而不重新加载,沿着auth
代码传递。 - 构建在上面的行,有javascript处理程序,那:
- 当接收到认证码时,按照这里的指示发起请求,为id_token交换认证码。
- 当id_token被接收时,调用c# Script函数对id_token做进一步的操作。
或者,我可以将redirect_uri
设置为后端服务器上的端点,并执行验证令牌->id_token流使用Google客户端sdk。但是,对于这种方法,我想知道我是否能够
- 验证令牌后->id_token流在后端服务器上完成,关闭当前窗口,Tab B,并返回Tab a。
- 在我们回到Tab A后,将Unity重定向到一个特定的场景(不再是登录场景,而是用户在经过身份验证后被定向到的主页)。
如果我能得到任何帮助,我将非常感谢:')
编辑:为了更清晰,我想要实现的是facebook Unity sdk在他们的FB.LogInWithReadPermissions()
中所做的事情。整个验证码->access_token流是无缝的,我被重定向到Tab A中的Unity应用程序,最后使用access_token。
我设法找到一个Javascript解决方案来实现我的第一个方法。不同之处在于
- 我的应用程序将永远不会在生产
- 与我的Facebook OAuth实现的一致性,
我使用隐式流而不是授权代码流,尽管出于安全考虑,它不是推荐的方式。但是,我认为您可以轻松地使用授权代码流,检索授权代码并将其传递到后端以交换id令牌。(据我所知,你不能使用Javascript/XHR请求来进行这种交换)
所以,流程是从我的c#脚本,我从.jslib
文件调用Javascript函数。基本上,该函数检测OAuth窗口何时重定向回我的redirect_uri
,然后从重定向的URI中获取access_token
参数,并调用c# Script函数。从那里,你应该能够做任何你需要做的事情(改变场景,发送到你的后端,等等)。请注意,这里有一个try/catch,因为如果您试图从Google Sign In页面获取信息,将会出现错误。
文件如下:
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);
}
// ...
}
当然,这是超级黑客,我不是很熟悉Javascript,所以不知道上面代码的含义,但它适用于我的用例。