如何在Node.Js Express和Handlebars中使用中间件重定向到根路由?

o8x7eapl  于 2023-05-17  发布在  Node.js
关注(0)|答案(1)|浏览(209)

我想在登录后重定向到根路由。在根路由中,有一个中间件来检查用户是具有“admin”还是普通“user”角色。我在浏览器中加载了带有auth cookie的根页面,但没有获得任何用户。经过isUser/isAdmin中间件后,结果应该是user/admin。管理员已在系统中注册。用户将注册,然后登录。
这是我的根路由。

router.get('/', async (req, res) => {
    
    Title.findAll()
    .then(title => {
  
      NavItems.findAll()
        .then(nitem => {
          NavItem2.findAll()
            .then(navitem2 => {
              NavItem3.findAll()
              .then(navitem3 => {
                   PaperTopic.findAll()
                   .then(topic =>{
                    
                    Paper.findAll({
                      limit: 3,
                      order: [
                                ['postingDate', 'DESC'],
                                ['postingTime', 'DESC']

                      ],
                      include:[{
                        model: PaperTopic,
                        //required: true
                   
                      },{
                        model:Category
                      }]
                    })
                    .then(paper=>{

                       Category.findAll()
                       .then(category=>{

                          NavItem4.findAll()
                          .then(navitem4=>{
                            //console.log(JSON.stringify(paper, null, 2))
                            res.render('home/index', {
                              layout: 'index-layout',
                              title,
                              nitem,
                              navitem2,
                              navitem3,
                              topic,
                              paper,
                              category,
                              navitem4
                              })
                          })
                     
                      })
                    
                       })
                   })
              
              })
             

            })
             

        })

    })

})

这是我的登录路径。

router.post('/login', (req, res) => {

     if (!req.body.email || !req.body.password) {
      res.render('auth/login',{
        error_msg: 'Please Give Email And Password',
        layout: false
    })
    }
    else {
      User.findOne({ where: { email: req.body.email } })
        .then(user => {
          if (!user) {
            res.render('auth/login',{
                error_msg: 'This Email Is Not Registered',
                layout: false
            })
          } else {
  
                    bcrypt.compare(req.body.password, user.password, (err, isMatch) => {
                    if (err) throw err;
                    if (isMatch) {
                        const token = jwt.sign({
                            username: user.name,
                            email: user.email,
                            role: user.role
                        }, process.env.JWT_SECRET,{
                            expiresIn: '1h'
                        });
                       
                        res.cookie('ntoken', token,{
                            httpOnly:true
                        })
                        res.redirect('/');
                      

                    }
                    else {
                        res.render('auth/login',{
                            error_msg: 'Invalid Password',
                            layout: false
                        })
                    }

                });
            }

        }).catch(err => console.log(err));
  
    }
  
  })

这是我的检查用户中间件。

const isUser = (req, res, next) =>{
const token = req.cookies.ntoken;
  try{
   
     const decoded = jwt.verify(token, process.env.JWT_SECRET);
     const {username, email, role} = decoded;
     req.username = username;
     req.email = email;
     req.role = role;
     if(req.role == "user"){
      next();
     }else{
        next("Require User Role");
     }
    
  }
  catch (err){
    console.log(err);
    next("Authentication Failure");
   
  }

}
module.exports = isUser;

这是我的checkAdmin中间件

const isAdmin = (req, res, next) =>{
 
    const token = req.cookies.ntoken;
      try{
       
         const decoded = jwt.verify(token, process.env.JWT_SECRET);
         const {username, email, role} = decoded;
         req.username = username;
         req.email = email;
         req.role = role;
         if(req.role === "admin"){
          next();
         }else{
           next("Require Admin Role");
          
         }
        
      }
      catch (err){
        console.log(err);
        next("Invalid Token");
       
      }
    
    }
    module.exports = isAdmin;

登录后我想用中间件重定向到根路由

router.get('/', isUser, async (req, res) => {
  Title.findAll()
  .then(title => {
    NavItems.findAll()
      .then(nitem => {
        NavItem2.findAll()
          .then(navitem2 => {
            NavItem3.findAll()
            .then(navitem3 => {
                 PaperTopic.findAll()
                 .then(topic =>{
                  
                  Paper.findAll({
                    limit: 3,
                    order: [
                              ['postingDate', 'DESC'],
                              ['postingTime', 'DESC']

                    ],
                    include:[{
                      model: PaperTopic,
                      //required: true
                 
                    },{
                      model:Category
                    }]
                  })
                  .then(paper=>{

                     Category.findAll()
                     .then(category=>{

                        NavItem4.findAll()
                        .then(navitem4=>{
                          res.render('home/index', {
                            layout: 'index-layout',
                            name: req.username,
                            email: req.email,
                            role: req.role,
                            title,
                            nitem,
                            navitem2,
                            navitem3,
                            topic,
                            paper,
                            category,
                            navitem4
                            })
                        })
                   
                    })
                  
                     })
                  
                 })
            
            })
           

          })
           

      })

  })

})

这是我的路线管理员登录后

router.get("/", isAdmin, async (req, res) => {

  console.log(req.email)
  Title.findAll()
  .then(title => {
    //console.log(title);
    NavItems.findAll()
      .then(nitem => {
        NavItem2.findAll()
          .then(navitem2 => {
            NavItem3.findAll()
            .then(navitem3 => {
                 PaperTopic.findAll()
                 .then(topic =>{
                  
                  Paper.findAll({
                    limit: 3,
                    order: [
                              ['postingDate', 'DESC'],
                              ['postingTime', 'DESC']

                    ],
                    include:[{
                      model: PaperTopic,
                      //required: true
                 
                    },{
                      model:Category
                    }]
                  })
                  .then(paper=>{

                     Category.findAll()
                     .then(category=>{

                        NavItem4.findAll()
                        .then(navitem4=>{
                          //console.log(JSON.stringify(paper, null, 2))
                          res.render('home/index', {
                            layout: 'index-layout',
                            name: req.username,
                            email:req.email,                       
                            role: req.role,
                            title,
                            nitem,
                            navitem2,
                            navitem3,
                            topic,
                            paper,
                            category,
                            navitem4
                            })
                        })
                   
                    })
                  
                     })
               
                 })
            
            })
           

          })
           

      })

  })

 })

这是我的索引布局.hbs

{{#if email}}
   {{#test role "admin"}}
   <li class="scroll-to-section"><a href="/admin/dashboard"><i class="fa fa-bars" aria-hidden="true"></i> {{name}}</a></li>
   {{else}} 
   <li class="scroll-to-section"><a href="/user/dashboard"><i class="fa fa-bars" aria-hidden="true"></i> {{name}}</a></li>
                  
   {{/test}}
    {{else}}
   <li class="scroll-to-section"><a href="/auth/login">Login</a></li>
   <li class="scroll-to-section"><a href="/auth/register">Register Now!</a></li>
   {{/if}}

我试过这个。我在浏览器中获得了主页和cookie。但在车把的页面,我没有得到用户名/电子邮件。我不明白问题出在哪里。问题出在路由器上还是中间件上,还是别的什么地方?请帮帮我……
我还有其他路由,例如/admin/dashboard和/user/dashboard

router.get("/admin/dashboard", isUser, async (req, res) => {})
router.get("/user/dashboard", isAdmin, async (req, res) => {})

36844;的变化,从这里开始。

这是我的中间件功能

const checklogin = (req, res, next) => {
  const token = req.cookies.ntoken;
    try {
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      if (!decoded) { return next(); }
  
      const { username, email, role } = decoded;
      const user = { email, role, username };
  
      req.user = user; 
      res.locals.user = user; 
    } catch (err) {
      console.log(err);
      res.sendStatus(500);
    }
  
    return next();
  };

module.exports = checklogin;
这是我的app.js

const home = require('./routes/home/home');
const auth = require('./routes/auth/auth');
const admin = require('./routes/admin/admin');
const user = require('./routes/user/user');
app.use('/', home);
app.use('/auth', auth)
app.use('/admin', admin)
app.use('/home', homepage)
app.use('/user', user);

我的home.js文件中的逻辑

const checklogin = require('../../middleware/checklogin');

router.get('/', async (req, res) => {

    Title.findAll()
    .then(title => {
      //console.log(title);
      NavItems.findAll()
        .then(nitem => {
          NavItem2.findAll()
            .then(navitem2 => {
              NavItem3.findAll()
              .then(navitem3 => {
                   PaperTopic.findAll()
                   .then(topic =>{
                    
                    Paper.findAll({
                      limit: 3,
                      order: [
                                ['postingDate', 'DESC'],
                                ['postingTime', 'DESC']

                      ],
                      include:[{
                        model: PaperTopic,
                        //required: true
                   
                      },{
                        model:Category
                      }]
                    })
                    .then(paper=>{

                       Category.findAll()
                       .then(category=>{

                          NavItem4.findAll()
                          .then(navitem4=>{
                            //console.log(JSON.stringify(paper, null, 2))
                            res.render('home/index', {
                              layout: 'index-layout',
                              title,
                              nitem,
                              navitem2,
                              navitem3,
                              topic,
                              paper,
                              category,
                              navitem4
                              })
                          })
                     
                      })
                    
                       })
                   
                    
                   })
              
              })
             

            })
             

        })

    })

})



router.get('/', checklogin, async (req, res) => {
 
    if(!(req.user && req.user.role === "admin")){
      res.sendStatus(401);
    }else{
    Title.findAll()
      .then(title => {
        //console.log(title);
        NavItems.findAll()
          .then(nitem => {
            NavItem2.findAll()
              .then(navitem2 => {
                NavItem3.findAll()
                .then(navitem3 => {
                     PaperTopic.findAll()
                     .then(topic =>{
                      
                      Paper.findAll({
                        limit: 3,
                        order: [
                                  ['postingDate', 'DESC'],
                                  ['postingTime', 'DESC']
  
                        ],
                        include:[{
                          model: PaperTopic,
                          //required: true
                     
                        },{
                          model:Category
                        }]
                      })
                      .then(paper=>{
  
                         Category.findAll()
                         .then(category=>{
  
                            NavItem4.findAll()
                            .then(navitem4=>{
                              res.render('home/index', {
                                layout: 'index-layout',
                                title,
                                nitem,
                                navitem2,
                                navitem3,
                                topic,
                                paper,
                                category,
                                navitem4
                                })
                            })
                       
                        })
                      
                         })
                     
                      
                     })
                
                })
               
  
              })
               
  
          })
  
      })
  }
  })
  

  router.get('/', checklogin, async (req, res) => {
 
    if(!(req.user && req.user.role === "user")){
      res.sendStatus(401);
    }else{
    Title.findAll()
      .then(title => {
        //console.log(title);
        NavItems.findAll()
          .then(nitem => {
            NavItem2.findAll()
              .then(navitem2 => {
                NavItem3.findAll()
                .then(navitem3 => {
                     PaperTopic.findAll()
                     .then(topic =>{
                      
                      Paper.findAll({
                        limit: 3,
                        order: [
                                  ['postingDate', 'DESC'],
                                  ['postingTime', 'DESC']
  
                        ],
                        include:[{
                          model: PaperTopic,
                          //required: true
                     
                        },{
                          model:Category
                        }]
                      })
                      .then(paper=>{
  
                         Category.findAll()
                         .then(category=>{
  
                            NavItem4.findAll()
                            .then(navitem4=>{
                              //console.log(JSON.stringify(paper, null, 2))
                              res.render('home/index', {
                                layout: 'index-layout',
                                title,
                                nitem,
                                navitem2,
                                navitem3,
                                topic,
                                paper,
                                category,
                                navitem4
                                })
                            })
                       
                        })
                      
                         })
                     
                      
                     })
                
                })
               
  
              })
               
  
          })
  
      })
  }
  })

module.exports = router

这是我的登录路线

router.post('/login', (req, res) => {

     if (!req.body.email || !req.body.password) {
      res.render('auth/login',{
        error_msg: 'Please Give Email And Password',
        layout: false
    })
    }
    else {
      User.findOne({ where: { email: req.body.email } })
        .then(user => {
          if (!user) {
            res.render('auth/login',{
                error_msg: 'This Email Is Not Registered',
                layout: false
            })
          } else {
  
                    bcrypt.compare(req.body.password, user.password, (err, isMatch) => {
                    if (err) throw err;
                    if (isMatch) {
                        const token = jwt.sign({
                            username: user.name,
                            email: user.email,
                            role: user.role
                        }, process.env.JWT_SECRET,{
                            expiresIn: '1h'
                        });
                       
                        res.cookie('ntoken', token,{
                            httpOnly:true
                        })
                        res.redirect('/');
                      

                    }
                    else {
                        res.render('auth/login',{
                            error_msg: 'Invalid Password',
                            layout: false
                        })
                    }

                });
            }

        }).catch(err => console.log(err));
  
    }
  
  })

我试过了。但我没有得到任何用户。最初,在app.js文件中,我尝试以如下方式调用app.use(checklogin)

app.use(checklogin)
    app.use('/', home);
    app.use('/auth', auth)
    app.use('/admin', admin)
    app.use('/home', homepage)
    app.use('/user', user);

在调用home之前,auth,admin使用app.use()路由。但它没有加载索引页。它说内部服务器错误。然后,我跳过中间件,尝试了以下操作。

app.use('/', home);
app.use('/auth', auth)
app.use('/admin', admin)
app.use('/home', homepage)
app.use('/user', user);

然后,索引将完美加载。登录后,我重定向到“/”。并使用checklogin中间件编写了'/'。登录后,我得到了cookie在浏览器中,但没有用户在哈佛商学院的网页。
@76484这是我的中间件,有新的逻辑

const jwt = require('jsonwebtoken');
const checklogin = (req, res, next) => {
  const token = req.cookies.ntoken;
    try {
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      if (!decoded) { return next(); }
  
      const { username, email, role } = decoded;
      //const user = { email, role, username };
  
      //req.user = user; // attach the user to `req` for use in our route handlers
      //res.locals.user = user; // attach the user to `res.locals` for use in our views
      req.username = username;
      req.email = email;
      req.role = role;
   
      
    } catch (err) {
      console.log(err);
      //res.sendStatus(500);
      return next()
    }
  
    return next();
  };

  module.exports = checklogin;

这是我的'/'路由处理程序。

router.get('/', checklogin, async (req, res) => {
    
        if(req.role === "admin"){
            
            res.render('home/index', {
                       layout: 'index-layout',
                       name: req.username,
                       email: req.email,
                       role: req.role,
                       title,
                       nitem,
                       navitem2,
                       navitem3,
                       topic,
                       paper,
                       category,
                       navitem4
                       })
                                  })
                            
        }
        else if(req.role === "user"){
            
        }else{
           
        }
        
    
    })
    
    module.exports = router

我像上面提到的那样检查了每条路线中的角色。最后,我终于得到了想要的结果。我不得不在catch块中放置return next()来加载索引页面,因为由于缺少token而没有加载索引。我也试过你的逻辑,但它不起作用。

2admgd59

2admgd591#

我认为你的代码中有很多不必要的重复。例如,isAdminisUser中间件功能看起来是相同的,但它们检查的是role。我们希望避免这种重复。
其次,您需要在/ GET处理程序中包含一个中间件,该中间件将以某种方式使经过身份验证的用户对象(如果存在)可用于呈现响应的代码。
我建议使用一个中间件函数将用户添加到req对象。我们可以称之为addUser

const addUser = (req, res, next) => {
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    if (!decoded) { return next(); }

    const { username, email, role } = decoded;
    const user = { email, role, username };

    req.user = user; // attach the user to `req` for use in our route handlers
    res.locals.user = user; // attach the user to `res.locals` for use in our views
  } catch (err) {
    console.log(err);
    res.sendStatus(500);
  }

  return next();
};

我们可以通过以下方式将此中间件附加到所有路由处理程序:

app.use(addUser);

然后,特定的处理程序将需要检查user对象,以获取它们需要应用的任何条件逻辑。例如:

app.get("/admin", async (req, res) => {
  if (!(req.user && req.user.role === "admin")) {
    res.sendStatus(401);
  } else {
    res.send("Hello, Admin");
  }
});

由于我们已经将user对象(当它存在时)添加到res.locals,因此它在我们的视图中可用:

{{#if user}}
  {{#test user.role "admin"}}
    <li class="scroll-to-section"><a href="/admin/dashboard"><i class="fa fa-bars" aria-hidden="true"></i> {{user.name}}</a></li>
  {{else}} 
    <li class="scroll-to-section"><a href="/user/dashboard"><i class="fa fa-bars" aria-hidden="true"></i> {{user.name}}</a></li>               
  {{/test}}
{{else}}
   <li class="scroll-to-section"><a href="/auth/login">Login</a></li>
   <li class="scroll-to-section"><a href="/auth/register">Register Now!</a></li>
{{/if}}

由于我们已经将user对象添加到res.locals并将中间件应用于所有处理程序,因此无需对“根”路由处理程序执行太多操作。它看起来像这样:

app.get("/", (req, res) => {
  res.render("home/index", {
    /* non-user variables */
  });
});

相关问题