Javascript “没有得到”;电邮;从firebase使用google登录验证id令牌

Javascript “没有得到”;电邮;从firebase使用google登录验证id令牌,javascript,python,firebase,firebase-authentication,google-signin,Javascript,Python,Firebase,Firebase Authentication,Google Signin,在我的web应用程序中,我使用firebase google登录来验证用户,流程如下 在前端,让用户使用firebase sdk登录,获取用户的idtoken并将其发送到服务器 服务器使用idtoken验证用户并从idtoken获取电子邮件 我使用的是python后端,我使用google.oauth2.id_令牌模块来验证令牌并解码令牌 问题是,对于少数用户来说,解码的令牌不包含电子邮件字段 在前端,我尝试添加userinfo.email作用域,但它仍然不起作用 我添加了这样的范围 google

在我的web应用程序中,我使用firebase google登录来验证用户,流程如下

  • 在前端,让用户使用firebase sdk登录,获取用户的idtoken并将其发送到服务器
  • 服务器使用idtoken验证用户并从idtoken获取电子邮件
  • 我使用的是python后端,我使用google.oauth2.id_令牌模块来验证令牌并解码令牌

    问题是,对于少数用户来说,解码的令牌不包含电子邮件字段

    在前端,我尝试添加userinfo.email作用域,但它仍然不起作用

    我添加了这样的范围

    googleProvider = new firebase.auth.GoogleAuthProvider(); googleProvider.addScope('https://www.googleapis.com/auth/userinfo.email')
    
    在后端,我像这样解码令牌

    decoded_token = google.oauth2.id_token.verify_firebase_token(auth_token, google.auth.transport.requests.Request())
    
    这是解码令牌为少数用户所包含的内容(我已将实际值更改为“sometext”)

    解码令牌中缺少电子邮件字段

    对于少数用户,电子邮件字段存在;对于少数用户,电子邮件字段不存在


    我不知道我遗漏了什么,我希望所有用户的解码令牌中都有电子邮件字段

    我没有找到我所问问题的确切解决方案,但我已经更改了我的流程,我之所以发布此消息,是因为我觉得它可能会对某些人有所帮助

    不获取电子邮件的原因是firebase登录流中的“允许创建具有相同电子邮件地址的多个帐户”设置。 此选项的作用是创建一个没有电子邮件地址的帐户,并且UID与具有相同电子邮件地址的其他帐户不同

    我所需要的是允许用户使用多个登录提供商(在我的例子中是facebook、google)登录

    如果某个用户与两个不同的登录提供商使用相同的电子邮件,并且在不同的时间使用不同的提供商(使用相同的电子邮件)登录,则该用户应链接到单个帐户

    下面解释了我是如何实现需求的

    在firebase登录流中,我将设置更改为“每个电子邮件地址一个帐户”

    为了实现这一要求,我必须处理以下情况

    案例1:

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

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

    User sign-in (not 1st time user account is created already) using a different sign-in-provider (with same email)
    
    处理案例1和案例2

    在前端,当用户在前端签名时,会将idtoken和电子邮件(使用email.scope获取电子邮件)发送到后端

    后端验证idtoken并获取该token的firebase用户\u id,然后检查数据库中与firebase用户\u id关联的帐户

    如果找不到与firebase用户id关联的帐户,它将创建一个新帐户,该firebase用户id作为密钥,并将电子邮件存储在该帐户中,并将所需的详细信息发送到前端。如果它找到一个帐户,它将发送与该帐户关联的详细信息

    处理个案3

    由于“每个电子邮件地址一个帐户”设置,当用户尝试使用新的登录提供商使用现有电子邮件登录时,firebase将抛出“身份验证/帐户存在且具有不同凭据”异常

    如本文所述,通过处理此异常,具有此新登录提供商的电子邮件将链接到现有firebase用户\u id


    然后流程与案例2类似,您可以使用user.providerData[0]!。电子邮件!若要在您使用“允许创建具有相同电子邮件地址的多个帐户”时获取电子邮件:


    你找到解决办法了吗?谢谢我使用
    facebook.com
    作为提供商也有同样的服务
    verifyIdToken
    不显示电子邮件地址。使用
    signInWithPopup(provider)
    在前端登录后,我确实获得了电子邮件地址。我在使用admin sdk函数
    admin.auth()时找到了答案。getUser(uid)
    在使用
    verifyIdToken
    获得uid后返回完整的用户详细信息
    User sign-in (not 1st time user account is created already) using a different sign-in-provider (with same email)
    
      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);