我试图弄清楚如何在轨道上混淆我的记录的ids.
例如:一个典型的路径可能看起来像http://domain/records/1,所以人们很容易推断网站获得的流量,如果他们只是创建一个新的记录.
我使用的一个解决方案是使用盐对id进行散列,但是由于我不知道这个函数是否是双射的,所以我最终将它存储在数据库的另一个列中,并重新检查其唯一性.
我正在考虑的另一个选择是生成随机哈希,并将其另存为另一列.如果它不是唯一的…只是生成另一个.
这样做最好的方法是什么?
解决方法
您可以使用内置的OpenSSL库来加密和解密您的标识符,这样您只需要在模型上覆盖to_param即可.您还需要使用Base64将加密数据转换为纯文本.我会把它粘在一个模块中,以便可以重用:
require 'openssl' require 'base64' module Obfuscate def self.included(base) base.extend self end def cipher OpenSSL::Cipher::Cipher.new('aes-256-cbc') end def cipher_key 'blah!' end def decrypt(value) c = cipher.decrypt c.key = Digest::SHA256.digest(cipher_key) c.update(Base64.decode64(value.to_s)) + c.final end def encrypt(value) c = cipher.encrypt c.key = Digest::SHA256.digest(cipher_key) Base64.encode64(c.update(value.to_s) + c.final) end end
所以现在你的模型需要看起来像这样:
class MyModel < ActiveRecord::Base include Obfuscate def to_param encrypt id end end
然后在您的控制器中,当您需要通过加密的ID找到记录时,您将使用以下内容:
MyModel.find MyModel.decrypt(params[:id])