简体   繁体   English

使用谷歌登录无法从 firebase 获取“电子邮件”验证 id 令牌

[英]Not getting "email" from firebase verify id token using google sign in

In my web application, I am using firebase google sign in to authenticate users,The flow is as follows在我的 web 应用程序中,我使用 firebase google 登录来验证用户,流程如下

  1. In the frontend make the user sign in using firebase sdk get the idtoken for the user send it to server在前端让用户使用 firebase sdk 登录,获取用户的 idtoken 将其发送到服务器
  2. Server uses the idtoken to verify the user and get email from the idtoken服务器使用 idtoken 验证用户并从 idtoken 中获取电子邮件

I am using a python backend and I use google.oauth2.id_token module to verify the token and to decode the token我正在使用 python 后端,我使用 google.oauth2.id_token 模块来验证令牌并解码令牌

The problem is for few users the decoded token doses not contain the email field问题是对于少数用户,解码的令牌不包含电子邮件字段

In the front-end I have tried adding the userinfo.email scope also still it is not working在前端,我尝试添加 userinfo.email 范围,但仍然无法正常工作

I added the scope like this我添加了这样的范围

googleProvider = new firebase.auth.GoogleAuthProvider(); googleProvider.addScope('https://www.googleapis.com/auth/userinfo.email')

in back-end i am decoding the token like this在后端,我正在像这样解码令牌

decoded_token = google.oauth2.id_token.verify_firebase_token(auth_token, google.auth.transport.requests.Request())

this is what the decoded token contains for few users (I have changed actual values to "sometext")这是少数用户的解码令牌包含的内容(我已将实际值更改为“sometext”)

{
    "picture": "somtext",
    "sub": "somtext",
    "user_id": "somtext",
    "name": "somtext",
    "iss": "https://securetoken.google.com/somtext",
    "firebase": {
      "sign_in_provider": "google.com",
      "identities": {
        "google.com": [
          "somtext"
        ]
      }
    },
    "exp": 1557566434,
    "auth_time": 1557562833,
    "iat": 1557562834,
    "aud": "somtext"
  }

email field is missing in the decoded token解码的令牌中缺少电子邮件字段

for few users email field is present for few it is not present对于少数用户电子邮件字段存在对于少数它不存在

I don't know what I am missing, I want to have email field in the decoded token for all users我不知道我错过了什么,我想在所有用户的解码令牌中有电子邮件字段

I did not find the exact solution for what I have asked but I have changed my flow, I am posting this because I feel like it may help some one我没有找到我所问的确切解决方案,但我已经改变了我的流程,我发布这个是因为我觉得它可能对某人有所帮助

the reason for not getting email is "Allow creation of multiple accounts with the same email address" settings in the firebase signin flow.没有收到电子邮件的原因是 firebase 登录流程中的“允许使用相同的电子邮件地址创建多个帐户”设置。 what this option does is it creates an account with no email address and a UID that is different than the other account with the same email address此选项的作用是创建一个没有电子邮件地址的帐户和一个与具有相同电子邮件地址的其他帐户不同的 UID

what I required was to allow users to use multiple sign-in-providers (facebook, google in my case) to sign in我需要的是允许用户使用多个登录提供商(在我的情况下是 facebook,google)来登录

if some user is using same email with 2 different sign-in-providers and sign-in using different providers(with same email) at different time that user should be linked to a single account如果某个用户使用同一电子邮件与 2 个不同的登录提供商并在不同时间使用不同的提供商(使用同一电子邮件)登录,则该用户应链接到单个帐户

how I implemented the requirement is explained below下面解释了我是如何实现要求的

In firebase sign-in flow I changed the setting to "One account per email address",在 Firebase 登录流程中,我将设置更改为“每个电子邮件地址一个帐户”,

I had to handle the following cases for implementing this requirement我必须处理以下情况才能实现此要求

case 1:情况1:

User sign-in for the 1st time(no user account is there for the user) using a sign-in-provider

case 2:案例2:

User sign-in (not 1st time user account is created already) using the same sign-in-provider

case 3:案例3:

User sign-in (not 1st time user account is created already) using a different sign-in-provider (with same email)

handling case 1 and case 2处理案例1和案例2

In front end when a user signs-in the front end sends the idtoken and the email(email is obtained using the email.scope) to the backend在前端,当用户登录时,前端将 idtoken 和电子邮件(使用 email.scope 获取电子邮件)发送到后端

backend verifies the idtoken and get the firebase user_id of that token then it checks the db for an account associated with the firebase user_id后端验证 idtoken 并获取该令牌的 firebase user_id 然后它检查与 firebase user_id 关联的帐户的数据库

if it cannot find an account associated with the firebase user_id, it creates a new account with that firebase user_id as a key and store the email in that account and sends the required details to front end.如果它找不到与 firebase user_id 关联的帐户,它会创建一个以该 firebase user_id 作为密钥的新帐户,并将电子邮件存储在该帐户中,并将所需的详细信息发送到前端。 if it finds an account it sends the details associated with the account如果它找到一个帐户,它会发送与该帐户相关的详细信息

handling case3处理案例3

because of the "One account per email address" setting when a user try to sign-in using already existing email using a new sign-in provider firebase will throw an "auth/account-exists-with-different-credential" exception由于“每个电子邮件地址一个帐户”设置,当用户尝试使用新的登录提供程序使用现有电子邮件登录时,firebase 将引发“身份验证/帐户存在与不同凭据”异常

by handling this exception as explained here https://firebase.google.com/docs/auth/web/google-signin#handling-account-exists-with-different-credential-errors the email with this new sign-in-provider would be linked to the existing firebase user_id通过按照此处的说明处理此异常https://firebase.google.com/docs/auth/web/google-signin#handling-account-exists-with-different-credential-errors使用此新登录提供商的电子邮件将链接到现有的 firebase user_id

then the flow is like in case2那么流程就像case2

You can use user.providerData[0]!.email!您可以使用 user.providerData[0]!.email! to get email in case you are using "Allow creation of multiple accounts with the same email address":在您使用“允许使用相同电子邮件地址创建多个帐户”的情况下接收电子邮件:

  let bearerTokenID = req.cookies.BearerTokenID;
  let decodedToken = await admin.auth().verifyIdToken(bearerTokenID);
  let user = await admin.auth().getUser(decodedToken.uid);
  let email = user.providerData[0]!.email!;
  console.log("Email:", email);

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

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