我正在将Meteor应用程序与 Google 的One Tap集成。尝试使用 MeteorloginWithGoogle
来让用户保存到Meteor 帐户(内置在 Meteor.js 中)。其复杂性在于
One-Tap 库不是为了授权用户(即产生访问令牌),只是为了验证用户
因此,我必须做的是使用 Google Api 对用户进行身份验证,或者gapi
检索必要的access_token
和id_token
. 这篇文章的道具。
到目前为止,我得到的如下:
HTML
<div data-prompt_parent_id="g_id_onload" style={{ position: "absolute", top: "5em", right: "1em" }} id="g_id_onload"></div>
客户方
google.accounts.id.initialize({
prompt_parent_id: "g_id_onload",
client_id: "42424242-example42.apps.googleusercontent.com",
auto_select: false,
callback: handleCredentialResponse
});
const handleCredentialResponse = async oneTapResponse => {
// see the SERVER SIDE code, which is where validation of One Tap response happens
Meteor.call("verifyOneTap", oneTapResponse.credential, oneTapResponse.clientId, (error, result) => {
if (error) {
console.log(error);
}
if (result) {
// Initialize the JavaScript client library.
gapi.load("auth2", function() {
// Ready. Make a call to gapi.auth2.init or some other API
gapi.auth2.authorize(
{
client_id: oneTapResponse.clientId,
scope: "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
response_type: "code token id_token",
prompt: "none",
// this is the actual email address of user, example@gmail.com, passed back from the server where we validated the One Tap event...
login_hint: result.email
},
function(result, error) {
if (error) {
// An error happened.
console.log(error);
return;
}
//these are the authentication tokens taht are so difficult to capture...
let theAccessToken = result.access_token;
let theIdToken = result.id_token;
//*********************************
//this is the part that doesn't work
//trying to get it to create the account without another Google prompt...
Meteor.loginWithGoogle({ accessToken: theAccessToken, idToken: theIdToken, prompt: "none" }, function(err, res) {
if (err) {
console.log(err)
}
});
//*********************************
}
);
});
}
});
};
google.accounts.id.prompt(notification => {
//this just tells you when things go wrong...
console.log(notification);
});
服务器端
const { OAuth2Client } = require("google-auth-library");
const clientOA2 = new OAuth2Client("42424242-example42.apps.googleusercontent.com");
// the token and clientId are returned from One Tap in an object, are credential (token) and clientId (clientId)
verifyOneTap: async (token, clientId) => {
const ticket = await clientOA2.verifyIdToken({
idToken: token,
audience: clientId // Specify the CLIENT_ID of the app that accesses the backend
// Or, if multiple clients access the backend:
//[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
});
const payload = await ticket.getPayload();
//perform validation here so you don't get hacked...
return payload;
// If request specified a G Suite domain:
// const domain = payload['hd'];
}
尝试在客户端/服务器上以不同的方式编写此代码,以及考虑解决此问题的方法并仅注册 Meteor 的Accounts.createUser,但这并不理想。[options]
我传递给的有什么问题loginWithGoogle
?我会认为accessToken
并且idToken
足够了......
发生的情况是,在登录时,它确实让我通过 Google One Tap 的第一阶段登录,但后来我投入Meteor.loginWithGoogle
的选项不知何故未被识别:
这有效(一步流程的第一步)=>
但随后它再次要求登录:|
文档说明loginWithGoogle
格式通常为:
Meteor.loginWith<ExternalService>([options], [callback])
关于loginWithGoogle
:
选项还可能包括Google 的附加 URI 参数
Google 的附加 URI 参数
必需:client_id、nonce、response_type、redirect_uri、范围
可选:access_type、display、hd、include_granted_scopes、login_hint、prompt
不幸的是,它显然没有识别出[options]
我正在传递的东西,否则它会将用户保存到 MongoDB,而它没有这样做。