0

In my Rails 5.2 app I have this controller which sends a download link with a token parameter to a user:

class ArchivesController < ApplicationController

  def new
    # Create and email download link
  end

  def show
    archive = Archive.valid.find_by(:token => params[:id]) # Check if archive is still valid or has already expired
    if archive
      redirect_to rails_blob_path(archive.file)
    else
      flash[:notice] = "Invalid link!"
      redirect_to root_path
    end
  end

end

This works and correctly redirects to the rails_blob_path which is provided by Rails' ActiveStorage.

What bothers me is that clicking the download link will not only download the file but also open a new (blank!) browser tab. I guess this is due to the redirect in my controller action?

Is there any way to prevent browsers from opening a blank browser tab? In my eyes this is not required and may confuse the user.

In a previous version of my app I put the rails_blob_path directly in the email and the download was triggered without opening a new browser tab. However, I didn't like that approach for security reasons and there was no way to invalidate or expire records that had already been downloaded.

Tintin81
  • 9,821
  • 20
  • 85
  • 178
  • 1
    How does the link look like that the user clicks? How does the action look like that sends the file? – spickermann Jan 25 '20 at 20:13
  • @spickermann: This is the link in the email: `archive_url(@archive.token)`. I think the `new` action which sends the link is not really relevant here. It is fairly common. – Tintin81 Jan 25 '20 at 20:43

1 Answers1

1

If all you want is a download link, then a controller action is not necessary. You are correct in assuming the redirect_to is the cause of the blank page.

You can simply set the disposition of the link to attachment...something like this...

<%= link_to "Download", rails_blob_path(your_object, disposition: "attachment") %>
Mark Merritt
  • 2,625
  • 2
  • 12
  • 16
  • OK, this is exactly what I had in the previous version of my code. I don't want to reveal the `rails_blob_path` in my email, however. And there's no way to set an expiry date on it. Or is there? – Tintin81 Jan 25 '20 at 20:47
  • I know, I know. Exactly what I had before. It works! But I don't want it in my emails. – Tintin81 Jan 25 '20 at 20:49
  • The mailer just contains this URL: `archive_url(@archive.token)`. So it triggers the `show` action in my controller. – Tintin81 Jan 25 '20 at 20:59
  • So, instead of triggering the controller action, give a link to the `rails_blob_url` directly – Mark Merritt Jan 25 '20 at 21:00
  • OK, and how can I make sure that it will expire after one hour? (I need that feature for security reasons.) – Tintin81 Jan 25 '20 at 21:04
  • 1
    checkout [this answer](https://stackoverflow.com/questions/52571555/how-do-you-change-the-active-storage-service-url-expires-in-timeout/52573490#52573490) which is from the ActiveStorage maintainer. Essentially all you have to do is set your preferred expiry in an initializer...the example given is set to 1 hour! – Mark Merritt Jan 25 '20 at 21:08
  • Ah this could indeed be the solution. Hope it works with Rails 5.2. Will try that out tomorrow. Cheers! – Tintin81 Jan 25 '20 at 21:15