Passport.authenticate 导出-> passport.authenticate(一些东西)(req,res,next)?

Posted

技术标签:

【中文标题】Passport.authenticate 导出-> passport.authenticate(一些东西)(req,res,next)?【英文标题】:Passport.authenticate exporting -> passport.authenticate( some stuff ) (req, res, next)? 【发布时间】:2019-10-27 10:45:16 【问题描述】:

我不明白为什么在passport.authenticate 函数之后需要(req, res, next)

用这个和express,我跟着一个教程,没有把这段解释得太清楚

PS:一切正常,我只是不明白为什么需要这样做

const passport = require('passport')

module.exports = (req, res, next) => 
  passport.authenticate('jwt', (err, user) => 
    if (err || !user || user.isAdmin !== true) 
      res.status(403).send(
        message: 'Request blocked, only administrators'
      )
     else 
      req.user = user
      next()
    
  )(req, res, next)

作为中间件的函数调用

app.get('/admin', isAdmin, (req, res) => 
    res.send(
      message: 'You are an admin'
    )
  )

护照策略配置

passport.use(
    jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
    secretOrKey: config.jwtSecret
  , async (jwtPayload, done) => 
    try 
      const user = await User.findOne(
        where: 
          id: jwtPayload.id
        
      )
      if (!user) 
        return done(new Error(), false)
      
      return done(null, user)
     catch (err) 
      return done(new Error(), false)
    
  )
)

PSS:我必须为用户身份验证创建另一个名为 isUser.js 的文件,如果我想将它们放在同一个文件中并要求它们一样,我应该怎么做

const Auth = require('./Auth')
Auth.isUser
Auth.isAdmin

我试过了,但我不知道如何使用这种类型的函数:(

【问题讨论】:

【参考方案1】:

Express Route'snext() 调用下一个路由处理程序或应该在当前方法/中间件中处理完请求后处理请求的中间件。

所以按照你的代码(在代码中查看我的 cmets):

const passport = require('passport')

module.exports = (req, res, next) => 
  passport.authenticate('jwt', (err, user) => 
    if (err || !user || user.isAdmin !== true) 
      res.status(403).send(
        message: 'Request blocked, only administrators'
      )
     else 
      req.user = user // THE user OBJECT IS ADDED TO THE req OBJECT SO THE NEXT ROUTE HANDLING METHOD/MIDDLEWARE MAY GET ACCESS TO THIS ADDED user OBJECT AND MAY USE IT
      next() // THIS CALL THE NEXT ROUTE METHOD/MIDDLEWARE
    
  )(req, res, next)

所以在这里执行next() 之后,请求被传递给另一个名为isAdmin 的中间件来处理,该中间件将根据添加的用户对象检查当前用户是普通用户还是管理员用户从前面的中间件添加的请求中检索到req.user = user

因此,如果您想避免为 isAdmin 创建单独的文件,那么您可能会这样:

const passport = require('passport')
// INCLUDE YOUR AUTH MIDDLEWARE FILE HERE
const isAdmin = require('./PATH/TO/isAdmin')

    module.exports = (req, res, next) => 
      passport.authenticate('jwt', (err, user) => 
        if (err || !user || user.isAdmin !== true) 
          res.status(403).send(
            message: 'Request blocked, only administrators'
          )
         else 
          req.user = user
          // COMMENT OUT BELOW LINE
          // next()
          // IMPLEMENT THE AUTH LOGIC HERE, SOMETHING LIKE BELOW
          if (user.isAdmin()) 
          
        
      )(req, res, next)
    

希望对你有帮助

【讨论】:

以上是关于Passport.authenticate 导出-> passport.authenticate(一些东西)(req,res,next)?的主要内容,如果未能解决你的问题,请参考以下文章

对passport.use(strategy) done 功能及其与passport.authenticate 的关系感到困惑

passport.authenticate()如何确定successRdirect或failureRedirect?

在发布路线上使用 nodemailer 发送电子邮件并使用 passport.authenticate 将用户保存到 mongodb

模块导出,nodejs对于护照身份验证需要太长时间

Nodejs和PassportJs:如果身份验证失败,则不会调用passport.authenticate后重定向中间件

Passport Authenticate 功能在节点 api 中不起作用