使用中间件保护 Expressjs 路由

Posted

技术标签:

【中文标题】使用中间件保护 Expressjs 路由【英文标题】:Protect Expressjs routes using Middleware 【发布时间】:2021-09-06 14:25:30 【问题描述】:

晚上好!我会先说如果这不可能,我愿意接受其他建议。 我正在使用 MERN 堆栈创建一个非常简单的发票应用程序。我只想通过在路由之前添加一些中间件来保护我在后端的路由。我正在使用 Auth0 进行身份验证。我想对标头referer URL 做一个简单的比较,但是当页面第一次被重定向时,它有authorization_codestate 附加到 URL,然后当页面刷新时它的正常 URL 没有附上代码和状态。有没有办法获得状态和授权码?我也尝试过 cookie 验证,但问题是在重定向完成之前没有给出 cookie,所以中间件一直在发送错误。

我是应用程序身份验证层的新手,所以如果有更好的方法可以做到这一点,我会全力以赴。我也在考虑改用访问令牌,只是将获取访问令牌的逻辑放在中间件中。

// 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;

【问题讨论】:

我认为,如果您展示您目前拥有的相关代码,我们可以提供更好的帮助。 我添加了相关代码。一个重要的注意事项是我使用 Auth0 进行身份验证。 【参考方案1】:

如果情况是第一个 URL 在 URL 中具有状态和身份验证,然后客户端获得重定向,并且您希望从重定向中获得相同的信息,那么您有两个选择:

    您可以将状态和身份验证信息放入重定向 URL,这样当重定向返回到您的服务器时,它就在重定向 URL 中。

    假设第一个和第二个 URL 是同一个域,您可以将状态和身份验证信息添加到该客户端的会话对象中(表明您已经在使用 express-session,因此每个客户端都有一个会话) .然后,当重定向 URL 请求进来时,您可以从会话对象中获取该信息。

    同样,假设第一个和第二个 URL 是同一个域,您可以在第一个 URL 的响应中添加一个 cookie,该 cookie 将包含第二个 URL 所需的任何信息,如果需要,该信息可以在服务器端加密.

    如果使用两个 URL 跨域,那么您可以在服务器上创建自己的跨域会话对象,将其插入到服务器端 Map 对象中,并使用唯一生成的 sessionID 作为键并将该 sessionID 放入重定向网址。然后,当您获得第二个 URL 时,您可以从 URL 中获取 sessionID,在您的服务器端 Map 中查找与其关联的数据,并让数据可供您的服务器使用。

【讨论】:

#2 对我来说是最好的选择,它有多安全?这可能是一个愚蠢的问题。 @AS10 - 会话对象是许多服务器在登录后用于验证后续请求的身份验证的对象。会话对象本身仅存储在服务器上,并由存储在 cookie 中的加密密钥索引。如果您使用 https 作为传输(对于任何级别的登录安全都必须这样做)并且您将会话 cookie 设置为 httpOnly,那么它非常安全,并且只有在某些外部代理可以物理访问客户端计算机时才能真正违反。

以上是关于使用中间件保护 Expressjs 路由的主要内容,如果未能解决你的问题,请参考以下文章

ExpressJS:承诺和错误处理中间件

基于 Content-Type 标头的 Expressjs 路由器

javascript NodeJs ExpressJS中间件,允许特定于bot / crawler的路由。基于OS项目的Prerender.IO中间件用于节点。

ExpressJS教程

为 Express 定义 Websocket 路由

ExpressJS包的用途?