Protected sharing link in Ruby on Rails
I don't know of any gems for protected links and I can imagine that it is hard to find a common denominator for such an individual feature.
However, here's how I would implement such a system. The basic idea is to substitute the id with a practically "unguessable" token
.
1 - create an token
column (index: true
, unique: true
) for the resource you want to protect
2 - In the model, add validations, generator, callback and override to_param
validates :token, presence: true
validates :token, uniqueness: true
before_validation :generate_token, on: :create
def generate_token
begin
self.token = SecureRandom.urlsafe_base64(64, false)
end while self.class.find_by(token: token)
end
def to_param
token
end
3 - Change the routes to use :token
as url parameter
resources :things, param: :token
4 - Change the controller to find by token instead of id
@thing = Thing.find(params[:id]) # change this
@thing = Thing.find_by(token: params[:token]) # to this
Now, thing_url(@thing)
will return a url you can safely share:
http://example.com/things/KSwdmTuDSVOGLTHtjK-RU78x7Bme_g-noTrNcovrtXioxPletLvNK35ia_F8CpIBtNDv-_xQ5bZ8uuv18msD4w
Of course, you need to replace thing
and Thing
with your model name, respectively.
Ruby on Rails private link sharing: Google Docs Style
I would have a separate controller that uses a hash value to reference the event.
Something simple like the created_at + user_id hashed to create a unique reference.
You could also simply skip the check on a certain action but I would much prefer the first solution .
Creating unique Token for link that can only be accessed with the said link?
This is how I solved the to_param issue. I just simply removed it and reorganized the routes for the specific member route.....
When using:
resources :orders, param: :order_token do
get 'order_confirmation', :on => :member
end
In my routes, I am able to go to the URL i want. Although, after an order is created, it still directs me to a route using the :id.
I then change my redirect to:
redirect_to order_confirmation_order_path(@order.order_token)
And it works.
I also removed my to_param
override.
Related Topics
How to Remove Duplicates in a Hash in Ruby on Rails
Why Does .All? Return True on an Empty Array
Set Locale Automatically in Ruby on Rails
How Do Version Numbers Work for Mri Ruby
Ruby: Could Not Find a Temporary Directory
Add a CSS Class to <%= F.Submit %>
Paperclip Error: Model Missing Required Attr_Accessor for 'Avatar_File_Name'
Ruby 'Pass by Value' Clarification
Can You Install Documentation for Existing Gems
Ruby 2.7 Says Uri.Escape Is Obsolete, What Replaces It
Bootstrap Datepicker Default Value Simple_Form_For
How to Check Ruby Syntax Error in Ruby Code
Adding a Background Image in Ruby on Rails 2 in CSS