【问题标题】:The use of next() in middlewaresnext() 在中间件中的使用
【发布时间】:2020-09-09 17:28:15
【问题描述】:

我是编程新手,我一直在关注 Colt Steele 的网络开发人员训练营,并试图创建一个简单的博客应用程序。我已经附上了整个代码,但我想关注的部分是

function isLoggedIn(req, res, next) {
if(req.isAuthenticated()) {
        return next();
    }
req.session.redirectTo = req.originalUrl;
res.redirect("/login");}

在这种情况下,我尝试使用中间件 isLoggedIn 来检查用户是否只有在登录之后才能添加新专辑或博客文章。但是点击后,如果用户已登录,则添加新专辑,它会将我带回登录页面。

经过一些研究,我尝试将 req.originalUrl 存储在 req.session.returnTo 中。这应该在我们使用中间件的任何地方存储用户 GET 请求的 URL。

登录路径如下

//handling login logic
app.post('/login', passport.authenticate("local", 
    {
    failureRedirect: "/login"
}), (req, res) => { 
    let returnTo = req.session.returnTo ? req.session.returnTo : '/albums'
    delete req.session.returnTo;   
    res.redirect(returnTo);
})

这里我从 Passport 对象中删除了 successRedirect,因此我不会过早地重定向并在回调中处理重定向到 req.session.returnTo。

我的主要假设是 next() 会运行 res.render,但它似乎没有运行,我不知道为什么。

const express            = require('express'),
      app                = express(),
      mongoose           = require('mongoose'),
      bodyParser         = require('body-parser'),
      expressSanitizer   = require('express-sanitizer'),
      methodOverride     = require('method-override'),
      passport           = require('passport'),
      LocalSrategy       = require('passport-local'),
      User               = require('./models/users');

//APP CONFIG          
mongoose.connect('mongodb+srv://arya123:password1234567890@crudclust-gc08c.mongodb.net/<dbname>?retryWrites=true&w=majority', { 
    useNewUrlParser: true, 
    useUnifiedTopology: true,
    useFindAndModify: false
    }).then(() => {
        console.log('Connected to DB!')
    }).catch(err => {
        console.log('ERROR', err.message);
    })

app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressSanitizer());
app.use(express.static("public"));
app.use(methodOverride("_method"));

//PASSPORT CONFIG
app.use(require("express-session")({
    secret: "Nico wins cutest dog!",
    resave: false,
    saveUnititialized: false,
    cookie: { secure: true }
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalSrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.serializeUser(User.deserializeUser());

//MODEL CONFIG
let cataSchema = new mongoose.Schema({
    title: String,
    artist: String,
    body: String,
    art: String
});

let Catalog = mongoose.model('Catalog', cataSchema);

// let George = new Catalog ({
//     title: "All things must pass",
//     artist: "George Harrison",
//     body: "This is an album"
// });
// George.save();


//ROUTES
app.get('/', (req, res) => {
    res.redirect('/albums');
});

app.get('/albums', (req, res) => {
        Catalog.find({}, function(err, catalogs){
            if(err){
                console.log("ERROR!");
            } else {
               res.render("index", {catalogs: catalogs}); 
            }
        });
}); 

//NEW ALBUM
app.get('/albums/new', isLoggedIn, (req, res) => {
    res.render("new");
});

//POST ROUTE
app.post('/albums', (req, res) =>  {
    console.log(req.body);
    Catalog.create(req.body.catalog, (err, newCatlog) => {
        if(err){
            res.render('/albums/new');
        }
        else{
            res.redirect('/albums');
        }
    });
});

//SHOW
app.get('/albums/:id', (req, res) =>{
    Catalog.findById(req.params.id, (err, foundCatalog) => {
        if(err){
            res.redirect('/albums');
        }
        else{
            res.render('show', {catalog: foundCatalog});
        }
    });
});

//EDIT
app.get('/albums/:id/edit', (req, res) => {
    Catalog.findById(req.params.id, (err, foundCatalog) => {
        if(err){
            res.redirect('/albums');
        }
        else{
            res.render('edit', {catalog: foundCatalog})
        }
    });
});

//UPDATE ROUTE
app.put('/albums/:id', (req, res) => {
    req.body.catalog.body = req.sanitize(req.body.catalog.body);
    console.log(req.body.catalog);
    console.log(req.params.id);
    console.log("===================")
    Catalog.findByIdAndUpdate(req.params.id, req.body.catalog, (err, updated) => {
        if(err){
            console.log(err);
            console.log("===============");
            res.redirect('/albums');
        }
        else{
            res.redirect("/albums/"+ req.params.id);
        }
    });
});

//DELETE ROUTE
app.delete('/albums/:id' , (req, res) => {
    Catalog.findByIdAndRemove(req.params.id, (err, removed) => {
        if(err){
            console.log(err);
            console.log(req.params.body);
            console.log("==============");
            res.redirect('/albums');
        }
        else{
            res.redirect('/albums');
        }
    });
});

//===========
//AUTH ROUTES
//===========

//Show register form
app.get('/register',(req, res) => {
    res.render('register');
})

//SIGN UP
app.post('/register', (req, res) => {
    let newUser = new User({username: req.body.username});
    User.register(newUser, req.body.password, (err, user) => {
        if(err){
            console.log(err);
            return res.redirect("register")
        }
        passport.authenticate("local")(req, res, () => {
            res.redirect('/albums')
        })
    })
   
});

//SHOW LOGIN
app.get("/login", (req, res) => {
    res.render('login')
})
//handling login logic
app.post('/login', passport.authenticate("local", 
    {
    failureRedirect: "/login"
}), (req, res) => { 
    let returnTo = req.session.returnTo ? req.session.returnTo : '/albums'
    delete req.session.returnTo;   
    res.redirect(returnTo);
})

//LOGOUT ROUTE
app.get("/logout", (req, res) => {
    req.logout();
    res.redirect("/albums")
})

function isLoggedIn(req, res, next) {
    if(req.isAuthenticated()) {
            return next();
        }
    req.session.redirectTo = req.originalUrl;
    res.redirect("/login");
}

//PORT
const port = process.env.PORT || 3000;

app.listen(port, () =>{
    console.log(`Now listening on Port: ${port}`);
})

【问题讨论】:

    标签: node.js mongodb express passport.js


    【解决方案1】:

    那么next() 做了什么?

    如果你遇到这样的路线

    app.post("/login", auth, middleware1, middleware2, middleware3, lastMiddleware);
    

    我这里有很多中间件。你需要知道你的请求总是从左边的中间件传到右边的。

    这意味着您从 auth 中间件开始。

    假设您已经完成了auth,并且您想继续使用下一个中间件middleware1,您将如何做到这一点?

    为此,您需要next()。它将跳转到下一个中​​间件到middleware1

    如果您想跳转到下一个中​​间件,请反复使用next()

    假设您在最后一个中间件上,通常您会向用户发送响应。但是,如果您不发回回复并使用next(),会发生什么?

    您有点“跳出”当前路线app.post("/login"),并且您的请求检查其他路线是否与他请求的路线匹配。 通常没有路由匹配,你应该登陆404错误页面,通常在服务器脚本的末尾定义。可能是这样的

    app.use(function() {
       res.send("Error cannot find")
    })
    

    【讨论】:

      猜你喜欢
      • 2021-05-21
      • 2019-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多