我的应用程序上有谷歌登录:相关代码大致如下:
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
,并且用作verifyIdToken
中audience
的client_id
是相同的。audience
的client_id
应该是前端应用程序中用于获取id_token
的client_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
?我无法找到任何关于requiredAudience
和audience
之间区别的文档,但是请确保您只发送{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
,也会导致获取用户信息