【问题标题】:How to protect static folder in express with passport如何用护照保护快递中的静态文件夹
【发布时间】:2014-02-15 15:15:35
【问题描述】:

我有一个基于 express 的项目,需要基于护照的身份验证。

后台是一个用作静态文件的 angularjs 应用程序。

我的验证码完全基于https://github.com/jaredhanson/passport-local/blob/master/examples/express3-no-connect-flash/app.js

如果您未通过身份验证,请不要为 Angular 应用程序提供服务。我尝试在 /admin 路由上添加 ensureAuthenticated ,但它使路由不起作用(404)。一旦我删除了 ensureAuthenticated,就会提供 /admin。

app.use(express.static(path.join(__dirname, 'public')));
app.use('/admin', ensureAuthenticated, express.static(path.join(__dirname, 'admin')));
//serve routes
app.use(app.router);

公用文件夹包含登录页面。

我怎样才能做到这一点?

【问题讨论】:

  • 如果他们在未登录时点击/admin 路由,您能否使用中间件(连接)重定向到登录?
  • 这就是我想要做的,但没有成功。如果没有,则确保已验证重定向到登录。但是有了这个,它在未登录时工作,但登录时我在 /admin 上有一个 404
  • 我想更多的是app.use(function(req, res, next) { if (!req.user)... }
  • 它有效,因此您应该发布完整的答案,我会将其标记为有效。谢谢,这个想法是创建一个中间件,而不是尝试将调用链接到 app.use

标签: node.js express passport.js


【解决方案1】:

遇到了同样的问题,这就是我最终要做的!

app.use 不允许您以这种方式链接中间件。各种种类 app.VERB 函数可以,但 app.use 不可以。这是一个中间件 一次。

如果您将 2 个中间件拆分为单独的调用,您应该得到 你想要的结果:

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

Cannot use basic authentication while serving static files using express

【讨论】:

  • 来自上面的源代码:@Mathias 制作和编辑 - 从 express 版本 4.x 开始,您可以将多个中间件作为数组、参数或两者的混合传入 app.use。使静态文件授权安全现在是:
【解决方案2】:

您可以使用中间件检查路由并在他们未登录并访问管理页面时重定向它们,例如(未经测试):

app.use(function(req, res, next) {
    if (req.user == null && req.path.indexOf('/admin') === 0)
    {
        res.redirect('/login');
    }
    next(); 
});

【讨论】:

  • 这对我不起作用。当文件夹位于静态路径时,它似乎不会通过 app.use 路由。
  • 如果您在另一个app.use 下方添加“静态”部分(由next() 调用),例如here,您的答案对于像我这样的新手来说会更清楚。我正在同时学习快递、护照、承诺等。还是谢谢。
  • 这是在任何其他调用之前进行授权检查的好方法,在调用 res.redirect 之后要小心一件事@ 这个函数应该返回以防下一个函数是某种 API 调用并尝试设置标头或对请求执行任何其他操作。
【解决方案3】:
app.use('/admin', function(req,res,next){
 if(req.user){
   return express.static(path.join(__dirname, 'public'));
 } else {
   res.render(403, 'login', {message:'Please, login!'});
 }
});

//serve routes
app.use(app.router);

【讨论】:

  • 答案看起来很合理,但对它为什么起作用的一些解释会有所帮助。
  • 对于路由'/admin',我们挂载中间件,由匿名函数定义,如果请求对象中存在用户对象,则返回静态中间件,或者通过使用登录表单呈现403页面来停止请求处理。
  • 对我不起作用,请求只是卡住了没有响应!还有 app.use(app.router);在 express 4.x 中被删除
【解决方案4】:

express@4.16.4+passport-jtw@0.4.0passport-jwt@4.0.0 的更新

首先设置一个护照身份验证策略。如果使用 jwt,则可以从查询参数中获取标记,否则可以使用另一个提取函数(或多个使用 Jwt.ExtractJwt.fromExtractors()

passport.use('basic-user',
    new Jwt.Strategy({
        ...jwtConfig.options,
        jwtFromRequest: Jwt.ExtractJwt.fromUrlQueryParameter('token')
    }, verifyUser)
);

然后您可以在提供静态文件之前使用护照身份验证功能

app.use('/files', [
    passport.authenticate(['basic-user'], { session: false }),
    express.static(path.join(__dirname, 'files')) //make sure you access proper directory
])

【讨论】:

    【解决方案5】:

    接受的答案感觉有点片面(在某些情况下可能不起作用),所以这里有一个更冗长和笼统的答案:

    // Here we'll attach the user object. The correct ordering 
    // of these middleware functions is important.
    app.use(
      '/some-restricted-static-path',
      passport.authenticate("bearer", { session: false })
    );
    
    // As the user object should now be attached (if authorized), we can now
    // verify it to be so.
    app.use('/some-restricted-static-path', (req, res, next) => {
      if (!!req.user) {
        // The user exists, we can continue.
        // Here you can also validate the role etc if necessary.
        next();
      } else {
        // No user object found, terminate the pipeline with .end().
        res.status(401).end();
      }
    });
    
    // And finally, here's the actual handler that won't be accessed if 
    // something went wrong earlier.
    app.use(
      '/some-restricted-static-path',
      express.static(
        path.join(
          __dirname,
          "../dist/attachments"
        )
      )
    );
    

    解释:在 Express 中,中间件是一个一个处理的。如果其中一个中间件终止该进程,则将跳过它之后的每个中间件。因此,知道这一点后,我们可以先附加用户对象,然后对其进行验证,最后授予或拒绝访问。

    【讨论】:

      【解决方案6】:

      您还可以将中间件链接为数组来实现此目标:

      app.use('/admin', [ensureAuthenticated, express.static(path.join(__dirname, 'admin'))]);
      

      【讨论】:

      • 这对我有帮助,因为在 express v4 中无法使用单独的 app.use('/admin', ensureAuthenticated);
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 2022-08-17
      • 2020-05-29
      • 2021-05-20
      相关资源
      最近更新 更多