使用自定义令牌的Firebase身份验证

时间:2017-02-14 23:39:13

标签: ruby-on-rails ruby firebase firebase-authentication jwt

我有一个firebase项目,我试图从我的rails服务器进行身份验证,创建一个自定义令牌,其中包含文档中的文件ruby-jwt,但我一直得到同样的错误:

  

auth / invalid-custom-token,自定义标记格式不正确。请查看文档。

credentials.json来自我在Google控制台中创建的服务帐户,uid从前端发送到api。

def generate_auth_token(uid)
  now_seconds = Time.now.to_i
  credentials = JSON.parse(File.read("credentials.json"))
  private_key = OpenSSL::PKey::RSA.new credentials["private_key"]
  payload = {
      :iss => credentials["client_email"],
      :sub => credentials["client_email"],
      :aud => 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
      :iat => now_seconds,
      :exp => now_seconds+(60*60), # Maximum expiration time is one hour
      :uid => uid.to_s,
      :claims => {:premium_account => true}
    }
  JWT.encode(payload, private_key, 'RS256')
end

在jwt.io

中看起来像这样
{
  "iss": "defered@defered.iam.gserviceaccount.com",
  "sub": "defered@defered.iam.gserviceaccount.com",
  "aud": "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
  "iat": 1486824545,
  "exp": 1486828145,
  "uid": "4",
  "claims": {
     "premium_account": true
   }
}

4 个答案:

答案 0 :(得分:1)

请看一下我的firebase_id_token宝石 它完全符合您的要求。

答案 1 :(得分:1)

似乎已接受的答案找到了一种将身份验证从Firebase链接到Rails的方法,但是最初的问题似乎是在询问如何将Rails身份验证链接到Firebase(这是我正在尝试做的事情)。

要将身份验证逻辑保留在Rails中(例如,来自Devise)并与Firebase共享,请首先从项目设置的Service Accounts页面中以.json文件的形式获得Firebase服务器密钥。< / p>

您只需要此文件中的private_keyclient_id,我建议将它们存储为环境变量,以免它们在源代码中泄漏。

接下来,制作一个普通的Ruby对象(PO​​RO),它将插入User并吐出Firebase可以理解的JSON Web令牌(JWT):

class FirebaseToken
  def self.create_from_user(user)
    service_account_email = ENV["FIREBASE_CLIENT_EMAIL"]
    private_key = OpenSSL::PKey::RSA.new ENV["FIREBASE_PRIVATE_KEY"]

    claims = {
      isCool: "oh yeah"
    }

    now_seconds = Time.now.to_i
    payload = {
      iss: service_account_email,
      sub: service_account_email,
      aud: "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
      iat: now_seconds,
      exp: now_seconds + (60*60), # Maximum expiration time is one hour
      uid: user.id,
      # a hash to pass to the client as JSON
      claims: claims
    }
    JWT.encode payload, private_key, "RS256"
  end
end

现在通过您的应用程序布局中的javascript将此JWT发送给经过身份验证的用户:

window.firebaseJWT = "#{FirebaseToken.create_from_user(current_user)}";

在前端代码中,您现在可以使用此令牌对用户进行身份验证:

firebase
  .auth()
  .signInWithCustomToken(window.firebaseJWT)
  .catch(error => {
    console.error(error);
  });

当他们退出您的应用程序时,请记住将他们从firebase中注销:

firebase
  .auth()
  .signOut()
  .then(() => {
    // Sign-out successful.
  })
  .catch(error => {
    console.error(error);
  });

答案 2 :(得分:0)

我找到了一种更好的身份验证方式,我只是发送firebase为您提供的令牌,并使用我需要的信息在轨道上进行验证。

答案 3 :(得分:0)

检查您的密钥是否用双引号引起来,而不是单引号,因为它们包含'\ n'转义序列。如果密钥与文档中未指定一样,则会抛出auth / invalid-custom-token令牌错误。