跳到內容 跳到搜尋

Active Record 簽署的 ID

命名空間
方法
S

類別公開方法

signed_id_verifier_secret

設定在 Rails 外部使用 Active Record 時簽署 ID 驗證器實例所使用的機密金鑰。在 Rails 內部,這會自動使用 Rails 應用程式金鑰產生器設定。

# File activerecord/lib/active_record/signed_id.rb, line 13
class_attribute :signed_id_verifier_secret, instance_writer: false

實例公開方法

signed_id(expires_in: nil, expires_at: nil, purpose: nil)

傳回使用預先設定的 ActiveSupport::MessageVerifier 實例產生的簽署 ID。

這個簽署的 ID 防竄改,因此可以安全地透過電子郵件傳送或與外界共用。不過,與使用 ActiveSupport::MessageVerifier 簽署的任何訊息一樣,簽署的 ID 並未加密。僅編碼且防竄改。

這表示 ID 可以由任何人解碼;不過,如果遭到竄改(變成指向另一個 ID),那加密簽章便不再相符,而且系統會將簽署的 ID 視為無效,並在傳遞給 find_signed(或使用 find_signed! 引發錯誤)時傳回 nil。

此外,也可以設定為到期(預設為不過期),並使用特定目的縮小範圍。如果在呼叫 find_signed 之前,已超過到期日期,則 ID 找不到指定的記錄。如果設定了目標用途,這也必須符合才行。

如果你不小心讓簽署的 ID 在外流傳,而你希望比到期日期更早將其收回(或者你可能忘記設定到期日期!)你可以使用目的來實質製作 signed_id 的版本,如下所示

user.signed_id purpose: :v2

然後將你的 find_signed 呼叫變更為需要這個新的目的。任何沒有使用這個目的建立的舊簽署 ID 都將不再找到此記錄。

# File activerecord/lib/active_record/signed_id.rb, line 131
def signed_id(expires_in: nil, expires_at: nil, purpose: nil)
  raise ArgumentError, "Cannot get a signed_id for a new record" if new_record?

  self.class.signed_id_verifier.generate id, expires_in: expires_in, expires_at: expires_at, purpose: self.class.combine_signed_id_purposes(purpose)
end