Skip to content

Commit 68b6a1c

Browse files
authored
Merge pull request rails#52064 from feliperaul/improve_message_verifier_and_signed_id_docs
[ci skip] Improve ActiveSupport::MessageVerifier and ActiveRecord::SignedId docs
2 parents 445529c + ad20d9e commit 68b6a1c

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

activerecord/lib/active_record/signed_id.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,16 @@ def combine_signed_id_purposes(purpose)
106106

107107

108108
# Returns a signed id that's generated using a preconfigured +ActiveSupport::MessageVerifier+ instance.
109+
#
109110
# This signed id is tamper proof, so it's safe to send in an email or otherwise share with the outside world.
111+
# However, as with any message signed with a +ActiveSupport::MessageVerifier+,
112+
# {the signed id is not encrypted}[link:classes/ActiveSupport/MessageVerifier.html#class-ActiveSupport::MessageVerifier-label-Signing+is+not+encryption].
113+
# It's just encoded and protected against tampering.
114+
#
115+
# This means that the ID can be decoded by anyone; however, if tampered with (so to point to a different ID),
116+
# the cryptographic signature will no longer match, and the signed id will be considered invalid and return nil
117+
# when passed to +find_signed+ (or raise with +find_signed!+).
118+
#
110119
# It can furthermore be set to expire (the default is not to expire), and scoped down with a specific purpose.
111120
# If the expiration date has been exceeded before +find_signed+ is called, the id won't find the designated
112121
# record. If a purpose is set, this too must match.

activesupport/lib/active_support/message_verifier.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ module ActiveSupport
3030
# self.current_user = User.find(id)
3131
# end
3232
#
33+
# === Signing is not encryption
34+
#
35+
# The signed messages are not encrypted. The payload is merely encoded (Base64 by default) and can be decoded by
36+
# anyone. The signature is just assuring that the message wasn't tampered with. For example:
37+
#
38+
# message = Rails.application.message_verifier('my_purpose').generate('never put secrets here')
39+
# # => "BAhJIhtuZXZlciBwdXQgc2VjcmV0cyBoZXJlBjoGRVQ=--a0c1c0827919da5e949e989c971249355735e140"
40+
# Base64.decode64(message.split("--").first) # no key needed
41+
# # => 'never put secrets here'
42+
#
43+
# If you also need to encrypt the contents, you must use ActiveSupport::MessageEncryptor instead.
44+
#
3345
# === Confine messages to a specific purpose
3446
#
3547
# It's not recommended to use the same verifier for different purposes in your application.

railties/lib/rails/application.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,20 @@ def message_verifiers
212212
# It is recommended not to use the same verifier for different things, so you can get different
213213
# verifiers passing the +verifier_name+ argument.
214214
#
215+
# For instance, +ActiveStorage::Blob.signed_id_verifier+ is implemented using this feature, which assures that
216+
# the IDs strings haven't been tampered with and are safe to use in a finder.
217+
#
218+
# See the ActiveSupport::MessageVerifier documentation for more information.
219+
#
215220
# ==== Parameters
216221
#
217222
# * +verifier_name+ - the name of the message verifier.
218223
#
219224
# ==== Examples
220225
#
221-
# message = Rails.application.message_verifier('sensitive_data').generate('my sensible data')
222-
# Rails.application.message_verifier('sensitive_data').verify(message)
223-
# # => 'my sensible data'
224-
#
225-
# See the ActiveSupport::MessageVerifier documentation for more information.
226+
# message = Rails.application.message_verifier('my_purpose').generate('data to sign against tampering')
227+
# Rails.application.message_verifier('my_purpose').verify(message)
228+
# # => 'data to sign against tampering'
226229
def message_verifier(verifier_name)
227230
message_verifiers[verifier_name]
228231
end

0 commit comments

Comments
 (0)