谷歌登录:后端验证



我的应用程序上有谷歌登录:相关代码大致如下:

var acc = await signInService.signIn();
var auth = await acc.authentication;
var token = auth.idToken;

这给了我一个很好的长令牌,然后我用 HTTP POST 将其传递给我的后端(这工作正常),然后尝试验证。我的颤振树和后端服务器(即nodejs/restify)中都有相同的google-services.json文件。后端代码大致为:

let creds = require('./google-services.json');
let auth = require('google-auth-library').OAuth2Client;
let client = new auth(creds.client[0].oauth_client[0].client_id);
. . .
let ticket = await client.verifyIdToken({
idToken: token,
audience: creds.client[0].oauth_client[0].client_id
});
let payload = ticket.getPayload();

这始终返回我的错误"错误的收件人,有效负载受众!= 必需的受众"。

我还尝试在 GCP 控制台单独注册并改用这些密钥/client_id,但结果相同。在哪里可以找到可以正确验证此令牌的有效client_id?

这里的问题是用于创建 OAuth2Client 的client_id,并且用作verifyIdTokenaudienceclient_id是相同的。audienceclient_id应该是前端应用程序中用于获取id_tokenclient_id

以下是来自谷歌文档的示例代码。

const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client(CLIENT_ID);
async function verify() {
const ticket = await client.verifyIdToken({
idToken: token,
audience: CLIENT_ID,  // 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 = ticket.getPayload();
const userid = payload['sub'];
// If request specified a G Suite domain:
//const domain = payload['hd'];
}
verify().catch(console.error);

这是文档的链接。

希望这有帮助。

另一个快速的解决方案可能是将参数"受众"的名称更改为"必需受众"。它对我有用。如果您从谷歌复制了代码,也许谷歌文档已经过时了。

client.verifyIdToken({
idToken,
requiredAudience: GOOGLE_CLIENT_ID,  // 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]
});

我一直在 google-auth-library 版本8.7.0中遇到这个问题,并且只有在您有一个CLIENT_ID需要验证时才会遇到解决方法。 像这样创建OAuth2客户端后:

const googleClient = new OAuth2Client(process.env.GOOGLE_CLIENT_ID);

您无需在verifyIdToken函数中传递CLIENT_ID,因为它使用googleClient对象来创建身份验证网址。

上面已经提到requiredAudience工作而不是audience,但我注意到requiredAudience适用于{client_id : <CLIENT_ID>}。所以也许你指的是creds.client[0].oauth_client[0]而不是creds.client[0].oauth_client[0].client_id?我无法找到任何关于requiredAudienceaudience之间区别的文档,但是请确保您只发送而不是{client_id : <CLIENT_ID>}

谷歌文档:链接

verifyIdToken()的调用签名不需要audience参数。这在更新日志中也有说明。所以你可以跳过它,它会起作用。文档对此有点误导。

这也是使用requiredAudience起作用的原因,因为它实际上没有被该方法使用,所以它与不提供它是一样的。

对我来说,我错误地尝试使用我的(firebase)项目的"普通",基于Web的客户端ID(在下载的"client_id"中,出于服务器目的,json密钥文件),

108xxxxxxxx

谷歌云项目的 id,

902xxxxxx

但我应该使用的是专门用于使用我的OAuth"臂"的应用程序的客户端ID。 就我而言,这是针对谷歌脚本项目,我需要在https://console.cloud.google.com/apis/credentials中查找我的项目(OAuth 凭据)并将客户端 ID 复制到其中,

902xxxxxx-abcdefghixxxxxxx.apps.googleusercontent.com

找出后端应该是什么的另一种方法是将 JWT 令牌放入 https://jwt.io(或只是自己解码)。 您应该使用的正确客户端 ID 位于"aud"(受众)字段下。 在我将我的客户端 ID 交换为我的 OAuth 客户端后,一切正常。

使用requiredAudience不是正确的答案!!

我遇到了与提出此问题的人相同的错误消息

错误

:收件人错误,有效负载受众!= 必需受众

我正在使用 8.1.0 版本进行google-auth-library,即使我的前端和后端都使用相同的 Google Oauth 2.0 客户端 ID,我仍然会收到此错误

当我尝试按照@David117Master的建议将audience更改为verifyIdToken函数中的requiredAudience时,似乎一开始就能解决问题。但是,即使我尝试在前端和后端使用不同的Client Id,我也能够获取用户帐户信息!!

这背后的原因由@Chuks Jr.回答解释。

所以我的解决方案只是将 npm 包升级到最新版本 (8.8.0)

npm i google-auth-library

然后我在verifyIdToken函数中使用 backaudience键,如果前端和后端使用不同的Client Id,它将始终返回错误

我还发现,如果没有传入Client Id或使用requiredAudience,即使使用前端和后端的不匹配Client Id,也会导致获取用户信息

最新更新