Rails 5 has_secure_token 加密

scl*_*m72 6 ruby encryption ruby-on-rails access-token rails-api

在 Ruby on Rails has_secure_tokengem/feature 中,它在创建记录时创建一个唯一的标记,并将其以纯文本形式存储在数据库中。如果我使用该令牌授予用户对 API 的访问权限,将该令牌以纯文本形式存储在数据库中是否存在安全风险?

token我希望当该方法将令牌提交到数据库时有一种方法可以对列进行加密has_secure_token,类似于bcrypt将密码加密到数据库中的方式。

我尝试过使用 gems 来attr_encrypted存储令牌的哈希值,但它似乎与has_secure_token. 以下是我的模型当前的设置方式:

class User < ApplicationRecord
  has_secure_token :token
  # attr_encrypted :token, key: :encrypt_token, attribute: 'token'

  # def encrypt_token
  #   SecureRandom.random_bytes(32)
  # end
end
Run Code Online (Sandbox Code Playgroud)

被注释的代码是attr_encrypted已被证明不兼容的代码。如果有人知道是否有一种方法可以安全地加密数据库中的列,同时也使用has_secure_token,我将不胜感激!

如果需要更多信息或者这令人困惑,请告诉我。提前致谢!

小智 5

Rails 6 ActiveModel::SecurePassword#has_secure_password接受属性名称参数,并将使用 BCrypt 设置相应#{attribute}_digest列的值。默认属性名称为 ,password并且模型必须具有#{attribute}_digest属性的访问器。

带有密码和 api_token 的简化示例:

rails generate model User password_digest:string api_token_digest:string
Run Code Online (Sandbox Code Playgroud)

轨道 6

class User < ApplicationRecord
  has_secure_password #create a `password` attribute
  has_secure_password :api_token, validations: false

  before_create do
    self.reset_token = SecureRandom.urlsafe_base64
  end
end
Run Code Online (Sandbox Code Playgroud)

在 Rails 6 之前,您可以直接调用 BCrypt 来加密令牌。

require 'bcrypt'

class User < ApplicationRecord
  has_secure_password #create a `password` attribute

  before_create do
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost    
    self.api_token = SecureRandom.urlsafe_base64
    self.api_token_digest = BCrypt::Password.create(api_token, cost: cost)
  end
end
Run Code Online (Sandbox Code Playgroud)