Search code examples
node.jsreactjsexpressauthenticationauth0

Protect Expressjs routes using Middleware


GoodEvening! I will preface this by saying that if this is not possible, I am open to other suggestions. I am creating a pretty simple invoice application using the MERN stack. I just want to protect my routes on the backend by adding some middleware before the route. I am using Auth0 for authentication. I want to do a simple comparison of the header referer URL, but when the page is first redirected it has the authorization_code and state attached to the URL, and then when the page is refreshed its the normal URL without the code and state attached. Is there a way to get the state and authorization_code? I also tried to do cookie validation, but the problem with that is the cookie is not given until the redirect is complete, so the middleware kept sending errors.

I am new to the authentication layer of apps, so if there is a better way to do this I am all ears. I was also thinking about using the access token instead and just put the logic to get the access token in the middleware.

// server.js
  app.use(
    expressSession({
          secret: process.env.SESSION_SECRET,
          resave: false,
          saveUninitialized: false,
      })
  );
app.use(express.json());
app.use(cors());
app.use(express.static(path.join(__dirname, 'build')));
app.use('/', cookieValidationMiddleware,refererValidationMiddleware, StoreInvoiceRouter); // route that has the middleware
app.use('/', saveLoggedInUserMiddleware, UserInvoicesRouter);
app.use('/', UpdateUserProfileRouter);



app.get('*', async (req,res) => {

  res.sendFile(path.join(__dirname, 'build', 'index.html'));
  
  });
  
  //CookieValidation (not actually the cookie)
  var cookie = require('cookie');




const cookieValidation = (req,res,next) => {

    const headerHost = req.headers.host;
    const host = `localhost:8080`;
    if(headerHost === host) {

       console.log('[cookieValidation] Header: hosts match');
      next();
    } else {

      console.log('[cookieValidation] Header: Hosts do not match');
      return;
    }
   
   
     


};
 module.exports = cookieValidation;
 
 
 // RefererValidation (not referer validation anymore)
 


// TODO Change the code below to get the authorization code from the URL to use or find another method to protect this route.


const refererValidation = (req,res,next) => {    
          if(req.sessionID) {

          console.log('[refererValidation] Session Valid');
          next()
         } else {
             
          console.log('[refererValidation] Session IDs do not match');
          return;
         }
};
 module.exports = refererValidation;


Solution

  • If the situation is that the first URL has the state and auth in the URL and then the client gets a redirect and you want that same info from the redirect, you have a couple choices:

    1. You can put the state and auth info into the redirect URL so when the redirect comes back to your server, it's right there with the redirect URL.

    2. Assuming the first and second URLs are the same domain, you can add the state and auth info to the session object for that client (you show that you're already using express-session so you have a session for each client). Then, when the redirect URL request comes in, you can fetch that info from the session object.

    3. Again, assuming the first and second URLs are the same domain, you can add a cookie to the response to the first URL that will contain whatever info you need for the second URL and that info can be server-side encrypted if required.

    4. If going across domains with the two URLs, then you could create your own cross domain session object on the server, insert it into a server-side Map object with a uniquely coined sessionID as the key and put that sessionID in the redirected URL. Then, when you get the second URL, you can grab the sessionID out of the URL, look up the data associated with it in your server-side Map and have the data available for your server to use.