Jake Chambers
Jake Chambers

Reputation: 563

How to serve singular static files in express without exposing full '/static' folder?

I am creating a very simple project that uses JWT. I am serving everything via express, I do not have a frontend and backend. What I want to do is serve SPECIFIC html files based on the user's authorization (serving on https://localhost:3000 entry point server.js)

People keep recommending to use (server.js):

app.use(express.static('static'))

but this of course does not work as I can access ANY of those files by going to https://localhost:3000/whatever.i.want.

I have also tried (server.js):

app.use( '/secret' , authMiddleware, function(req,res){
    if(auth){
      res.sendFile(__dirname + '/static/secret.html')
    }
});

but gives 404s on my stylesheet and script, as well as some weird MIME type error

Refused to execute https://localhost:3000/script.js as script because "X-Content-Type: nosniff" was given and its Content-Type is not a script MIME type.

It works if I add:

app.get( '/styles.css' , function(req,res){
  res.sendFile(__dirname + '/static/styles.css')
});

app.get( '/script.js' , function(req,res){
  res.sendFile(__dirname + '/static/script.js')
});

But do I really have to do this for every single stylesheet and script I use? There has to be a better way!!!

1.) What is the best way that people do this? Specifically, is it possible to create authorized web-apps without using a frontend and serving all your static files from the backend?

2.) Is it necessary that your static directory is publicly accessible? Meaning you can only cast authorization constraints on certain endpoints, then use a script file that calls those endpoints? Which would still allow you to view the base HTML, just not any results of the API calls. Which in effect works but is gross.

File system

server.js
/static
  /blah.html
  /secret.html
  /secret.css
  /secret.js

Upvotes: 0

Views: 714

Answers (2)

vun
vun

Reputation: 1269

You can solve this by having a folder called public, which you can put all the css, js in that folder. And use static middleware to serve the public folder

app.use(express.static('public'))

Then there is another folder called secret, which you will build routes, validate JWT token and serving html files based on user permission

Upvotes: -2

eotfofiw
eotfofiw

Reputation: 119

If you want to selectively serve assets from the express server, you could do something like this:

let secrets = ['secrets.html', 'my_diary.html']

app.use((req, res, next) => {
    let shouldBeAuthorised = secrets.some(s => req.url.includes(s))
    if (shouldBeAuthorized)
        // check they are authorized to be served this content
    else
        // just serve the content, carry on... no need to worry
})

app.use(express.static('static'))

My use of req.url.includes is very shaky, and with a more complicated list of files, could result in you requiring authorization for files that aren't explicitly in the blacklist... but the basic structure of the above code should achieve what you're looking to achieve.

Upvotes: 0

Related Questions