I am curretnly using Elixir and the Phoenix Framework to build an API.
I want to make some files accessible with the api and I managed to use Plug.Satic to access the files but the problem is I can access them even if I am not logged in into the system
plug Plug.Static,
at: “img/files/”, from: “var/www/app/files/”, gzip: false
On all my routes defined in router.ex I use pipe_through [:authenticate] to limit the access to the data but I don’t know how to do it for the files urls.
Is it even possible ?
Thank you advance
4 Likes
Hi @Darkpingouin!
The router only invokes the pipelines for routes that it matches on. At the same time, plug Plug.Static
works as a pass-through: i.e. if it finds a matching route, it serves it, otherwise it continues. So I am thinking you could probably do something like this in your router:
pipeline :static do
plug Plug.Static, at: “img/files/”, from: “var/www/app/files/”, gzip: false
end
scope "/img/files" do
pipe_through [:authenticate, :static]
match "/*not_found", PageController, :not_found
end
In this case, if a static asset exists, it will be served. Otherwise, it will invoke PageController.not_found, which you can use to show a proper error message or just render the 404 page.
One other option is to not use Plug.Static at all and use Plug.Conn.send_file/3
directly.
7 Likes
Thanks for you answer, However when I try to use your method I get some page not found errors because it thinks I try to do some GET instead of just looking for the file
GET /img/files/img.png
Sent 404 in 80ms
I don’t know if I missed a step but I used your code I just remove the match “/*not_found” because I dont have any PageController in my project
The match "/*not_found"
is extremely important, otherwise Plug.Static won’t be invoked, as the router only invokes the pipeline once a route is found. So you need to add it back and implement to do something, even if that something is returning 404.
6 Likes
Thank you very much, I actually had some compilation errors on
match “/*not_found”, PageController, :not_found
Because it was missing a parameter to call the function. I added :* like this :
match(:*, “/*not_found”, PageController, :not_found)
And it works just like I wanted.
Thank you very much for your help 
3 Likes