【问题标题】:Add Google authentication to Firebase Real Time Database将 Google 身份验证添加到 Firebase 实时数据库
【发布时间】:2019-05-05 03:12:23
【问题描述】:

我正在使用 Firebase 实时数据库,我需要向它添加用户身份验证。用户只能以提供商身份使用 Google 登录。

当前数据库模式:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

新的模式应该是这样的:

// These rules grant access to a node matching the authenticated
// user's ID from the Firebase auth token
{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

在我的情况下我应该使用什么来进行身份验证? userID、Google providerIDtoken like described here?

这是存储数据无需认证的功能:

 createMeetup ({commit, getters}, payload) {
      console.log('index.js -> createMeetup')
      const meetup = {
        title: payload.title,
      }
      let imageUrl
      let key
      firebase.database().ref('meetups').push(meetup)
        .then((data) => {
          key = data.key
          return key
        })
        .then(() => {
          commit('createMeetup', {
            ...meetup,
            imageUrl: imageUrl,
            id: key
          })
        })
        .catch((error) => {
          console.log(error)
        })
    },

【问题讨论】:

  • 您应该使用 google plus 进行身份验证,并在用户尝试向节点读取或写入数据时自动检测到 UID

标签: javascript firebase vue.js firebase-realtime-database firebase-authentication


【解决方案1】:

对于您的用例,您似乎需要整理几个步骤。我猜您的应用程序已经可以连接/使用 Firebase,但本质上就是这些:

第 1 步 - 连接

像往常一样使用您的 API 密钥/配置连接到 Firebase,应该如下所示。

firebase.initializeApp(config)

另请参阅:https://firebase.google.com/docs/web/setup

您可能已经在某个地方拥有了这个。这不会改变,但如果您按照描述应用规则,您的用户将无法在刚连接后使用 Firebase。

第 2 步 - 身份验证

这基本上是在告诉 Firebase 谁已连接。这必须使用 Firebase 可以验证的令牌/方法来完成。使用 Google ID 是最常见的方法。

使用现有的 Google ID/用户登录

// Initialize a generate OAuth provider with a `google.com` providerId.
var provider = new firebase.auth.OAuthProvider('google.com');
var credential = provider.credential(googleUser.getAuthResponse().id_token);
firebase.auth().signInWithCredential(credential)

另见:https://firebase.google.com/docs/reference/js/firebase.auth.OAuthProvider#credential

或者让 Firebase SDK 做登录流程

var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(function(result) {
  // This gives you a Google Access Token. You can use it to access the Google API.
  var token = result.credential.accessToken;
  // The signed-in user info.
  var user = result.user;
  // ...
})

另见:https://firebase.google.com/docs/auth/web/google-signin

最后一个选项是您参考的文档的首选/建议。

如果如您所述,用户已经可以使用 Google 登录您的应用以使用其他功能,那么您应该已经在某处拥有登录流程。根据您的情况,为了简化您的应用程序,建议让 Firebase SDK/库接管此过程。

第 3 步 - 使用数据库

最后,在验证用户并应用您建议的规则后,您还需要确保您写入的路径在当前用户可访问的路径范围内。您可以将其放在一个简单的函数中以使其更容易。

const getUserRef = (ref) => {
  const user = firebase.auth().currentUser;
  return firebase.database().ref(`/users/${user.uid}/${ref}/`);
}

您当然不应该在每次想要获取数据库引用时都检索当前用户,但我认为这清楚地说明了需要采取的步骤。

【讨论】:

    【解决方案2】:

    您可以允许用户使用多种方法登录/验证。然后,您可以将它们合并到一个帐户中,如下所述:

    https://firebase.google.com/docs/auth/web/account-linking

    所以实际上归结为两个选项:

    1. 允许用户使用多种方式登录,例如 Facebook、Google、Github、基本用户名/密码等。
    2. 或者只允许一种登录方法,例如只允许使用 Google。

    您选择的任何选项都将帮助您决定使用哪个 ID。

    【讨论】:

    • 如果我选择 Google,这种使用 uid (auth.uid) 的数据库身份验证方法是否正确,还是我需要其他类似 proivderID 的方法? ` ".read": "$uid === auth.uid", ".write": "$uid === auth.uid"`
    • 用示例扩展@Francisco Mateo 的答案:Firebase 数据库规则不关心用户是使用 Google 身份验证还是其他提供商注册的。它只是检查用户是否已登录并提供 uid。因此,在您的上述安全规则中,所有登录用户都将能够访问存储在他们自己节点中的数据。
    • 如果您使用的是 firebase 身份验证,它有自己的方法。您可以检查您试图查看用户是否已通过身份验证的任何内容。所以SOMETHING.snapshot(whateverCode => { if (someFireAuthCheck) doStuff })
    • 换句话说,将 Auth 内容与 RTDB 内容结合起来,两者的用户的 uid 应该相同。好吧,如果不是大声笑,您可以使它们相同
    • 希望我在 Fransico 之前得到这个问题,哈哈,我喜欢 Firebase 的东西
    【解决方案3】:

    您问题中的身份验证规则仅说明用户可以读取/写入自己的(大概)用户数据。

    我假设您正在寻找一种授权用户创建聚会数据的解决方案,并且您应该创建类似于此的规则:

    这些规则允许任何登录的用户创建聚会

    {
      "rules": {
        "meetups": {
          "$meetupId": {
            ".read": "auth.uid != null",
            ".write": "auth.uid != null"
          }
        }
      }
    }
    

    将新的聚会数据推送到数据库的 code-sn-p 将根据用户是否登录自动尝试成功或失败。您无需专门告诉 Firebase 用户以何种方式登录。Firebase SDK 会为您处理身份验证。

    但是,如果您确实想要根据用户身份验证的登录类型提供不同的机制,您可以在规则中进行检查。例如,如果您想确保用户不仅仅是“匿名”登录。

    查看文档:https://firebase.google.com/docs/database/security/user-security#section-variable

    【讨论】:

      【解决方案4】:

      你在那儿找到了文档:Authenticate Using Google Sign-In with JavaScript

      您可以通过将 Google 登录功能集成到您的应用中,让您的用户使用他们的 Google 帐户向 Firebase 进行身份验证。您可以通过使用 Firebase SDK 执行登录流程或手动执行 Google 登录流程并将生成的 ID 令牌传递给 Firebase 来集成 Google 登录。

      开始之前:

      • 将 Firebase 添加到您的 JavaScript 项目中。
      • 在 Firebase 控制台中启用 Google 登录:
      • 在 Firebase 控制台中,打开 Auth 部分。
      • 在登录方法选项卡上,启用 Google 登录方法并点击保存。
      • 使用 Firebase SDK 处理登录流程 如果您正在构建一个 Web 应用程序,最简单的验证用户身份的方法是 Firebase 使用他们的 Google 帐户来处理登录流程 Firebase JavaScript SDK。 (如果您想在 Node.js 中对用户进行身份验证或 其他非浏览器环境,您必须手动处理登录流程。)

      要使用 Firebase JavaScript SDK 处理登录流程,请按以下步骤操作:

      创建 Google 提供程序对象的实例:

      var provider = new firebase.auth.GoogleAuthProvider();
      

      可选:指定您希望从身份验证提供程序请求的其他 OAuth 2.0 范围。要添加范围,请致电addScope()

      例如:

      provider.addScope('https://www.googleapis.com/auth/contacts.readonly');
      

      请参阅身份验证提供程序文档。 可选:要将提供商的 OAuth 流程本地化为用户的首选语言,而不显式传递相关的自定义 OAuth 参数,请在启动 OAuth 流程之前更新 Auth 实例上的语言代码。

      例如:

      firebase.auth().languageCode = 'pt';
      // To apply the default browser preference instead of explicitly setting it.
      // firebase.auth().useDeviceLanguage();
      

      可选:指定要随 OAuth 请求一起发送的其他自定义 OAuth 提供程序参数。要添加自定义参数,请使用包含 OAuth 提供程序文档指定的键和相应值的对象对已初始化的提供程序调用 setCustomParameters。

      例如:

      provider.setCustomParameters({
          'login_hint': 'user@example.com'
      });
      

      不允许保留所需的 OAuth 参数,将被忽略。有关更多详细信息,请参阅身份验证提供程序参考。 使用 Google 提供程序对象向 Firebase 进行身份验证。您可以通过打开一个弹出窗口或重定向到登录页面来提示您的用户使用他们的 Google 帐户登录。移动设备首选重定向方法。

      要使用弹出窗口登录,请调用 signInWithPopup:

      firebase.auth().signInWithPopup(provider).then(function(result) {
      
          // This gives you a Google Access Token. You can use it to access the Google API.
          var token = result.credential.accessToken;
          // The signed-in user info.
          var user = result.user;
          // ...
      
      }).catch(function(error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
          // ...
      });
      

      另请注意,您可以检索 Google 提供商的 OAuth 令牌,该令牌可用于使用 Google API 获取其他数据。 这也是您可以捕获和处理错误的地方。有关错误代码列表,请查看 Auth Reference Docs。

      要通过重定向到登录页面进行登录,请调用signInWithRedirect:

      firebase.auth().signInWithRedirect(provider);
      

      然后,您还可以在页面加载时通过调用 getRedirectResult() 来检索 Google 提供商的 OAuth 令牌:

      firebase.auth().getRedirectResult().then(function(result) {
          if (result.credential) {
              // This gives you a Google Access Token. You can use it to access the Google API.
              var token = result.credential.accessToken;
              // ...
          }
      
          // The signed-in user info.
          var user = result.user;
      }).catch(function(error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
          // ...
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-12
        • 2017-12-26
        • 1970-01-01
        • 2017-04-28
        • 1970-01-01
        • 1970-01-01
        • 2023-03-20
        相关资源
        最近更新 更多