问题描述
我是编程新手,我一直在关注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('/',res) => {
res.redirect('/albums');
});
app.get('/albums',res) => {
Catalog.find({},function(err,catalogs){
if(err){
console.log("ERROR!");
} else {
res.render("index",{catalogs: catalogs});
}
});
});
//NEW ALBUM
app.get('/albums/new',isLoggedIn,res) => {
res.render("new");
});
//POST ROUTE
app.post('/albums',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',res) =>{
Catalog.findById(req.params.id,foundCatalog) => {
if(err){
res.redirect('/albums');
}
else{
res.render('show',{catalog: foundCatalog});
}
});
});
//EDIT
app.get('/albums/:id/edit',res) => {
Catalog.findById(req.params.id,foundCatalog) => {
if(err){
res.redirect('/albums');
}
else{
res.render('edit',{catalog: foundCatalog})
}
});
});
//UPDATE ROUTE
app.put('/albums/:id',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,updated) => {
if(err){
console.log(err);
console.log("===============");
res.redirect('/albums');
}
else{
res.redirect("/albums/"+ req.params.id);
}
});
});
//DELETE ROUTE
app.delete('/albums/:id',res) => {
Catalog.findByIdAndRemove(req.params.id,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',res) => {
res.render('register');
})
//SIGN UP
app.post('/register',res) => {
let newUser = new User({username: req.body.username});
User.register(newUser,req.body.password,user) => {
if(err){
console.log(err);
return res.redirect("register")
}
passport.authenticate("local")(req,() => {
res.redirect('/albums')
})
})
});
//SHOW LOGIN
app.get("/login",res) => {
res.render('login')
})
//handling login logic
app.post('/login',res) => {
let returnTo = req.session.returnTo ? req.session.returnTo : '/albums'
delete req.session.returnTo;
res.redirect(returnTo);
})
//logoUT ROUTE
app.get("/logout",res) => {
req.logout();
res.redirect("/albums")
})
function isLoggedIn(req,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}`);
})
解决方法
那么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")
})