简体   繁体   English

Google 登录:后端验证

[英]Google Sign-In: backend verification

I have Google Sign-in working on my app: the relevant code is roughly:我有谷歌登录在我的应用程序上工作:相关代码大致是:

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

This gives me a nice long token, which I then pass to my backend with an HTTP POST (this is working fine), and then try to verify.这给了我一个很好的长令牌,然后我使用 HTTP POST 将其传递到我的后端(这工作正常),然后尝试验证。 I have the same google-services.json file in my flutter tree and on the backend server (which is nodejs/restify).我的 flutter 树和后端服务器(即 nodejs/restify)中有相同的 google-services.json 文件。 The backend code is roughly:后端代码大致是:

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();

This consistently returns my the error "Wrong recipient, payload audience.= requiredAudience".这始终返回我的错误“错误的收件人,有效负载受众。= requiredAudience”。

I have also tried registering separately with GCP console and using those keys/client_id instead, but same result.我也尝试过单独注册 GCP 控制台并改用这些密钥/client_id,但结果相同。 Where can I find the valid client_id that will properly verify this token?在哪里可以找到可以正确验证此令牌的有效 client_id?

The problem here is the client_id that is being used to create an OAuth2Client and the client_id being used as the audience in the verifyIdToken is the same.这里的问题是client_id正被用于创建OAuth2Client和client_id被用作audienceverifyIdToken是一样的。 The client_id for the audience should be the client_id that was used in your frontend application to get the id_token .client_idaudience应该是client_id这是在前端应用用于获取id_token

Below is sample code from Google documentation.以下是来自 Google 文档的示例代码。

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);

And here is the link for the documentation.这是文档的链接

Hope this helps.希望这可以帮助。

It has already been mentioned above that requiredAudience works instead of audience , but I noticed requiredAudience works for both {client_id: <CLIENT_ID>} and <CLIENT_ID>.上面已经提到requiredAudience代替audience起作用,但我注意到requiredAudience{client_id: <CLIENT_ID>}和 <CLIENT_ID> 都起作用。 So maybe you were referencing creds.client[0].oauth_client[0] instead of creds.client[0].oauth_client[0].client_id ?所以也许您引用的是creds.client[0].oauth_client[0]而不是creds.client[0].oauth_client[0].client_id I have not been able to find any docs on the difference between requiredAudience and audience , however make sure you are sending just the <CLIENT_ID> instead of {client_id: <CLIENT_ID>} .我无法找到任何关于requiredAudienceaudience之间区别的文档,但是请确保您只发送 <CLIENT_ID> 而不是{client_id: <CLIENT_ID>}

Google doc:link谷歌文档:链接

Another quick solution might be change the name of your param "audience" to "requiredAudience", it works to me, if you copied the code from google, maybe the google documentation is outdated.另一个快速解决方案可能是将您的参数“观众”的名称更改为“requiredAudience”,它对我有用,如果您从谷歌复制代码,则可能是谷歌文档已过时。

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]
  });

verifyIdToken() 's call signature doesn't require the audience parameter. verifyIdToken()的调用签名不需要audience参数。 That's also stated in the changelog .这也在变更日志中说明。 So you can skip it, and it'll work.所以你可以跳过它,它会起作用。 The documentation is kinda misleading on that.该文档对此有点误导。

It's also the reason why using requiredAudience works because it actually isn't being used by the method, so it's the same as not providing it.这也是使用requiredAudience起作用的原因,因为它实际上并没有被该方法使用,所以它与不提供它是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM