无法使用Google登录从Firebase接收“电子邮件”以验证ID令牌

时间:2019-05-11 08:45:02

标签: javascript python firebase firebase-authentication google-signin

在我的Web应用程序中,我正在使用Firebase Google登录来验证用户身份,流程如下

  1. 在前端,使用户使用firebase sdk登录获取用户将其发送到服务器的idtoken
  2. 服务器使用idtoken验证用户并从idtoken获取电子邮件

我正在使用python后端,并且使用google.oauth2.id_token模块来验证令牌并解码令牌

问题在于,少数用户的解码令牌剂量不包含电子邮件字段

在前端,我尝试添加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”)

{
    "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"
  }
解码令牌中缺少

电子邮件字段

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

我不知道自己缺少什么,我想在所有用户的解码令牌中包含电子邮件字段

2 个答案:

答案 0 :(得分:0)

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

未收到电子邮件的原因是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

在前端,当用户登录时,前端会将id令牌和电子邮件(使用email.scope获取电子邮件)发送到后端

后端验证idtoken并获取该令牌的firebase user_id,然后检查数据库中与firebase user_id关联的帐户

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

处理case3

因为当用户尝试使用新的登录提供商firebase使用已经存在的电子邮件登录时,“每个电子邮件地址一个帐户”设置将引发“ auth / account-exists-with-different-credential”例外

通过按照此处https://firebase.google.com/docs/auth/web/google-signin#handling-account-exists-with-different-credential-errors的说明处理此异常,具有此新登录提供商的电子邮件将链接到现有的Firebase user_id

然后流程就像案例2

答案 1 :(得分:0)

您可以使用user.providerData [0] !. 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);
相关问题