如何使用Firebase登录多个社交服务?

And*_*Lee 56 authentication facebook-authentication firebase firebase-security

我希望用户能够使用多个不同的身份验证提供程序(例如Facebook,Twitter或Github)对我的Firebase应用程序进行身份验证.经过身份验证后,我希望用户无论使用哪种身份验证方法都可以访问同一帐户.

换句话说,我想将多个身份验证方法合并到我的应用程序中的单个帐户中.如何在Firebase应用中执行此操作?

And*_*Lee 56


更新(20160521):Firebase刚刚发布了其Firebase身份验证产品的重大更新,该产品现在允许单个用户链接来自各种支持的提供商的帐户.要了解有关此功能的更多信息,请阅读iOS,WebAndroid文档.以下答案是出于历史原因.


核心Firebase服务提供了多种身份验证方法:https: //www.firebase.com/docs/security/authentication.html

Firebase的核心是使用安全的JWT令牌进行身份验证.导致生成JWT令牌的任何内容(例如在您自己的服务器上使用JWT库)都可以对Firebase的用户进行身份验证,因此您可以完全控制身份验证过程.

Firebase提供名为Firebase Simple Login的服务,这是生成这些令牌的一种方式(这提供了我们的Facebook,Twitter等身份验证).它适用于常见的身份验证方案,因此您可以在没有服务器的情况下快速启动和运行,但它不是唯一的身份验证方法,并且不是一个全面的解决方案. 

以下是使用Firebase简单登录允许多个提供程序登录的一种方法:

  1. 为每个用户存储一个规范用户标识符,并将每个特定于提供者的标识符映射到该一个规范id.
  2. 更新安全规则以匹配给定用户帐户上的任何凭据,而不是仅匹配一个.

在实践中,安全规则可能看起来像这样,假设您要启用Twitter和Facebook身份验证(或允许用户创建一个帐户,然后再添加另一个):

{
  "users": {
    "$userid": {
      // Require the user to be logged in, and make sure their current credentials
      // match at least one of the credentials listed below, unless we're creating
      // a new account from scratch.
      ".write": "auth != null && 
        (data.val() === null || 
        (auth.provider === 'facebook' && auth.id === data.child('facebook/id').val() || 
        (auth.provider === 'twitter' && auth.id === data.child('twitter/id').val()))"
    }
  },
  "user-mappings": {
    // Only allow users to read the user id mapping for their own account.
    "facebook": {
      "$fbuid": {
        ".read": "auth != null && auth.provider === 'facebook' && auth.id === $fbuid",
        ".write": "auth != null && 
          (data.val() == null || 
          root.child('users').child(data.val()).child('facebook-id').val() == auth.id)"
      }
    },
    "twitter": {
      "$twuid": {
        ".read": "auth != null && auth.provider === 'twitter' && auth.id === $twuid",
        ".write": "auth != null && 
          (data.val() == null || 
          root.child('users').child(data.val()).child('twitter-id').val() == auth.id)"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,您存储一个全局用户ID(可以是您选择的任何内容),并维护Facebook,Twitter等身份验证机制与主用户记录之间的映射.在为每个用户登录后,您将从用户映射中获取主用户记录,并将该id用作用户数据和操作的主存储.以上还限制并验证用户映射数据,这样只能通过谁已经拥有了Facebook一样,Twitter等用户ID下/用户/ $用户名/(Facebook的ID正确的用户写入|叽叽喳喳-id |等-ID).

这种方法可以让您快速启动并运行.但是,如果您有一个复杂的用例并希望完全控制身份验证体验,则可以在自己的服务器上运行自己的身份验证代码.您可以使用许多有用的开源库来执行此操作,例如everyauthpassport.

您还可以使用第三方身份验证提供程序进行身份验证.例如,您可以使用Singly,它具有开箱即用的各种集成,而无需编写任何服务器端代码.


Kum*_*uma 16

我知道这篇文章存在了几个月,但是当我遇到这个问题时,我花了很多时间来使代码更加灵活.基于上面的安德鲁代码,我稍微调整了一下代码.

样本数据存储:

userMappings
|---facebook:777
|   |---user:"123"
|---twitter:888
    |---user:"123"
users
|---123
    |---userMappings
        |---facebook: "facebook:777"
        |---twitter: "twitter:888"
Run Code Online (Sandbox Code Playgroud)

安全规则:

"userMappings": {
  "$login_id": {
    ".read": "$login_id === auth.uid",
    ".write": "auth!== null && (data.val() === null || $login_id === auth.uid)"
  }
},

"users": {
  "$user_id": {
    ".read": "data.child('userMappings/'+auth.provider).val()===auth.uid",
    ".write": "auth!= null && (data.val() === null || data.child('userMappings/'+auth.provider).val()===auth.uid)"
  }
}
Run Code Online (Sandbox Code Playgroud)

所以userMappings仍然是当Facebook,微博....登录我们仰望第一信息的userMappings' 用户将指向主帐号中的用户.因此,在通过Facebook或Twitter登录后,我们可以查找主用户帐户.在用户中,我们保留了可以访问其数据的userMapping列表.

创建新用户时,我们必须先在用户中创建一个帐户.用户中的用户 ID 可以是我们想要的任何内容.这很灵活,因为我们可以提供更多登录方法,如Google,Github,而无需添加更多安全规则.