Reliably display an image uploaded using paperclip gem

By default: the paperclip folder contains all attachments in the public directory.

I did not want to store attachments in the public directory for security reasons, so I saved them in the uploads directory in the root of the application:

 class Post < ActiveRecord::Base belongs_to :user has_attached_file :some_image, path: ":rails_root/uploads/:attachment/:id/:style/:filename" do_not_validate_attachment_file_type :some_image end 

I did not specify the url parameter because I do not need a URL for each image attachment. If url is specified: then ANYONE with this URL can access the image. It is not safe.

On the user#show : page, I want to actually display the image. If I used all the default values ​​for paperclip, I could just do this because the image will be in the public directory and the image will have a URL:

 <p> <strong>Some image:</strong> <%= image_tag @post.some_image %> </p> 

It seems that if I save the image attachments outside the public directory and do not specify the URL (again: by doing this to protect the image), then the image will not be displayed in the view.

I know how to allow all applications through pundit gem. However, image resolution is useless if the image is publicly available. Therefore, I am trying to make the image inaccessible to the public by deleting the url and saving the image outside the public directory, but then the image is no longer displayed in the view.

Refresh . My question really comes down to the following: my images are saved in my rails application. With paperclip: is there a way to safely display an image in a view? In other words: make sure that the image does not have its own separate URL (because ANYONE with this URL can access this image, which makes this image unprotected). Here are some examples of what I mean by reliably displaying an image:

  • Example # 1: Display an image only if the user is logged in. (The image does not have a separate URL, so there is no other way to access the image)
  • Example # 2: Only display an image if the user is associated with this image. (The image does not have a separate URL, so there is no other way to access the image)

Additional update . I know that I can safely send a file using send_file , which allows the user to upload an image, but this is not what I want to do here. I do not want the user to upload an image. Instead: I want the user to actually be able to see the image on the web page. I want to safely display / display the image on the page. Using send_file (as I understand it) allows the user to upload a file. It does not display the image on the page.

+5
source share
3 answers

You can use send_file . Assuming you have a secure_image action on your routes:

 resources :posts do member do get :secure_image end end 

and the following method in the appropriate controller:

 def secure_image send_file Post.find(params[:id]).some_image.path end 

You can use protected images in your views:

 <%= image_tag secure_image_post_path(@post) %> 

What happens here: usually Rails (either nginx or apache ) sends static files, directly bypassing security checks for speed reasons. But the request for the secure_image action goes through the stack of whole Rails, so it is protected by your authentication system.

+9
source

You can perform an action in one of the Rails controllers, which authenticates the user / permissions to view the image. Instead of rendering the view, the action can then send the image to its http response using send_file :

http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file

Then, as soon as you receive this action yourself, and you see that it displays an image in your browser, you can make img tags that point to the URL of this action.

Each image will have its own URL, but you have full control over what the URL is and who can access it.

+1
source

You can convert the image to Base64 format, and when displayed, you can convert it to an image.

Another way is to watermark your images so that the image is useless to others.

0
source

Source: https://habr.com/ru/post/1240303/


All Articles