ruby-on-rails - 使用自定义 token 的 Firebase 身份验证

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

我有一个 firebase 项目,我试图从我的 rails 服务器进行身份验证,如文档中所述,使用库 ruby​​-jwt 创建自定义 token ,但我不断收到相同的错误:

auth/invalid-custom-token, The custom token format is incorrect. Please check the documentation.

credentials.json 来 self 在 google console 中创建的服务帐户,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
   }
}

最佳答案

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

要将您的身份验证逻辑保留在 Rails 中(例如:来自 Devise)并与 Firebase 共享,请首先从您的 Service Accounts 中获取作为 .json 文件的 Firebase 服务器 key 。项目设置中的页面。

您只需要此文件中的 private_keyclient_id,我建议将其存储为环境变量,这样它们就不会泄露到源代码中。

接下来,制作一个普通的 ol' Ruby 对象 (PORO),它将接收一个 User 并输出一个 Firebase 可以理解的 JSON Web Token (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)}";

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

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

请记住在他们退出您的应用程序时让他们退出 firebase:

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

关于ruby-on-rails - 使用自定义 token 的 Firebase 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42238246/

相关文章:

ruby-on-rails - Rails - 具有自定义框架的 Multi-Tenancy 应用程序

Ruby:如何替换文件中的文本?

Android/FireStore 查询并返回自定义对象

javascript - “用户”不可分配给类型 'void'

mysql - SQL 查询中的时间周期问题。

ruby-on-rails - rails 生成器 : generate files based on already existing rails files

ruby-on-rails - 将 ruby​​ 参数合并到字符串中会引发错误的 url 错误

ruby-on-rails - 为什么 Puma 在 WSL 这么慢?

ruby-on-rails - #<RSpec 的未定义方法 `visit'

firebase - 如何使用 flutter cloud_firestore 包传递 firestore 身份验证 token