skip to Main Content

I am serving a PDF file on node server at this path – /content/assets/sample.pdf. I want to restrict unauthorize access to this PDF file. For that, I have applied the authentication to /content/assets/*

router.use('/content/assets/*', isAuthenticated, (req, res) => {
  const filePath = path.join(__dirname, '../../static', req.path);
  console.log(filePath);
  res.sendFile(filePath);
});

function isAuthenticated(req, res, next) {
  const userIsAuthenticated = true;
  
  if (userIsAuthenticated) {
    next();
  } else {
    res.status(403).send('Unauthorized');
  }
}

When I try postman to check this, I am able to restrict /content/assets/ but not /content/assets/sample.pdf

Is there anything I can do to restrict the PDF file ?

2

Answers


  1. You should use app.all instead of app.use. Why? Because the use function in Express middleware checks only for the path content/assets, so req.path in the case of app.use will be just content/assets but never the file path included. This might be confusing, but app.all ensures that the middleware applies to all HTTP methods and properly captures the file path.( bit confusing right ?! )

    Anyways if you use the app.all then it registers a middleware function that will be executed for all HTTP methods (GET, POST, PUT, DELETE, etc.) at the specified route pattern. It matches all HTTP methods commonly used for route-wide configurations or error handling.

    Solution :

    const express = require("express");
    const path = require("path");
    
    const app = express();
    
    function isAuthenticated(req, res, next) {
      const userIsAuthenticated = true;
    
      if (userIsAuthenticated) {
        next();
      } else {
        res.status(403).send("Unauthorized");
      }
    }
    
    app.all("/content/assets/*", isAuthenticated, (req, res) => {
      // try logging the req.path in case you want to test the app.use here 
      const filePath = path.join(__dirname,  '../../static', req.path);
      return res.sendFile(filePath);
    });
    
    app.listen(3000, () => {
      console.log("Server started at port 3000");
    });
    
    

    Read more about app.use vs app.all

    Login or Signup to reply.
  2. Actually, there are two problems here:

    The first problem here is that the file is located in your static directory, which you made public using some code like

    app.use(express.static(path.join(__dirname, 'static')));
    

    The static middleware without any restriction already makes your file public for all types of access. To limit its access, you can do it either way:

    • Move it into another directory which isn’t available for anonymous access.
    • Change the order of middlewares, so that the middleware which requires authentication always gets checked before the one that doesn’t.

    The second problem is using using a wildcard along with app.use(). The app.use() method by default matches the prefix of the URL, so no need to add a wildcard path here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search