LionelHutz

LionelHutz

What’s the correct way to serve certain assets to the client, only if that client is logged in as a user?

I’m new to web dev, and am using Phoenix & Elixir to learn serverside skills. As part of a small project, I’m trying to show a subset of images to the user, pulled from a larger fixed set of images. The particular subset requested by the client changes via some JavaScript & LiveView, each time a particular button is pressed.

So far, so good - I’ve been able to set that up. The total, fixed set of images all live in my priv folder, and the JS changes the url of the Image tags’ src attribute accordingly - thus, the required images are served as static files.

But, I’d like this feature, and any of this particular superset of images, to only be available if the user is logged in? I’ve added the standard auth features from phx.gen.auth and combined with LiveView, added the particular page this feature lives on to be scoped under the require_authenticated_user plug etc. But can’t seem to find how/if I can scope certain static file paths (or, rather, the entire folder of all these paths and subpaths) to be piped through the require_authenticated_user plug? I’ve looked online, but found little, and tried experimenting. Maybe I’m going about this wrong though, and it can’t be done?

My other option would be to store all these assets on my database, and have LiveView send them as data to the client, for the JS to display them as images? And it seems this would provide greater security, as what I’m ideally looking for is to hide the assets as much as possible from everything except the clientside JS, so that, say, even when logged in, the user couldn’t simply navigate to the URL of a particular image as an HTTP request, and then save that image.

But, I sensed that serving images like this via my postgres DB would be much more inefficient for several reasons (and so far, my reading has said that to be true) - but I’m a beginner, so can’t say for sure?

Is there a correct procedure for serving certain assets behind a layer of auth security?

Many thanks for all your time and help!

Showing Posts 1 to 5

LostKobrakai

LostKobrakai

Plug.Static is a plug like any other. You can use forward within the phoenix router to route to a plain plug or use any other way to wrap that plug to require authentication for access.

al2o3cr

al2o3cr

One thing to consider carefully: Plug.Static’s behavior for things like cache control will likely need tweaking, as the defaults are intended for files like assets that should be aggressively cached for a long time (the opposite of what you’d want).

Re: serving images as data and populating img tags with JS - most browsers offer a “Save Image As…” even for those images. You’ll need to consider exactly what user behaviors you’re trying to prevent.

LionelHutz

LionelHutz OP

Thanks so much for the tip. The true purpose of the images is actually to populate an HTML canvas - I think that’s less able to be saveable, right?

However, whilst security for this project is an actual concern/goal, my main focus is actually to showcase the best practices - at least to my level of study - of each of the WebDev patterns that I’m trying to demo.

With the tweaking needed that you’re suggesting, it sounds to me that Plug.Static might not be the intended/proper way of hiding assets behind auth, after all? I’m happy to go with a different option if that is considered better, the Plug.Static method was just my idea.

Or, maybe there’s no set/best way of doing it?

Thanks for your feedback, really appreciate it.

LionelHutz

LionelHutz OP

Ah ok, thanks. That sounds promising, and I’ve been looking into it, since. Will report back when I’ve been able to give it a good shot.

Thanks for your feedback! Very much appreciate it.

voltone

voltone

Plug.Static does mostly three things:

  1. Locating the requested file in the filesystem
  2. Handling content type, range and other headers
  3. Calling Plug.Conn.send_file/3,4,5 to efficiently stream the data from the filesystem to the socket

So if you want to handle step 1 yourself (with added authentication and authorization) you can just write a controller that handles the necessary headers and uses send_file to have similar performance/efficiency as Plug.Static

Edit: it won’t be quite as efficient, presumably, as Plug.Static is usually called early in the Endpoint, while controller action pass through all the Endpoint and Router plugs; but you need many of those anyway if you’re going to do session-based auth

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews