There are many ways of generating a signed link for
implementing things like invitation email, unsubscribe link
or password reset feature. You could add a
token field on the
model, use JWT tokens. But in the upcoming Rails versions, the
generate tamper-proof and verifiable ids
will be built into rails.
# user = User.find(1) # signed_user_id = user.signed_id # User.find_signed signed_user_id => [user record] # User.find_signed invalid_data => ActiveSupport::MessageVerifier::InvalidSignature
The secret to encode and decode messages is auto generated using
ActiveSupport::KeyGenerator. You can also provide your own secret key
ActiveRecord::Base inside of
The signed ids could also be configured to expire. There is also support for generating ids with specific purpose like password reset.
# user = User.find(1) # signed_user_id = expires_in: 15.minutes, purpose: :password_reset
The signed ids are generated and verified using ActiveSupport::MessageVerifier which creates HMAC signarutes as Base64-encoded string.
The feature will be available when Rails 6.1 is released.
If you want to start using it right away, then
it can be implemented as a model concern using
module SignedIds extend ActiveSupport::Concern def signed_id self.class.signed_id_verifier.generate id end private class_methods do def find_signed(signed_id) if id = signed_id_verifier.verified(signed_id) find(id) end end def signed_id_verifier ActiveSupport::MessageVerifier.new signed_id_verifier_secret digest: 'SHA256' end def signed_id_verifier_secret @_signed_id_verifier_secret ||= Rails.application.config.signed_id_verifier_secret end end end