【问题标题】:Exporting middleware globally to all routes将中间件全局导出到所有路由
【发布时间】:2018-07-14 05:00:46
【问题描述】:

所以我一直在使用 PassportJS 向我的网站添加身份验证。我有兴趣选择性地显示反映用户是否登录或他/她是否是文档所有者的内容。

我有以下文件

app.js(入口点)

//Express set up
let express = require("express");
app = express();
serverPort = 8000;
io = require('socket.io')();

//BodyParser set up
bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));


//Mongoose set up
mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/Woof");

//Models settings
Dog = require("./models/dog");
User = require("./models/user");

//Seed file set up and run!
seed = require("./models/seed");
seed();

//Routes
app.use('/public', express.static(__dirname + '/public'));
app.use(require('./routes/dogOwners'));
app.use(require('./routes/landing'));
app.use(require('./routes/loginAndRegister'));
app.use(require('./routes/map'));
app.use(require('./routes/dog'));

//req.user avalaible to all routes
app.use(function(req,res,next){
  res.locals.currentUser = req.user;
  next();
});

//App settings
app.set('port', serverPort);
app.set('view engine', 'ejs');
app.set('views', 'views');
app.set('sockets', []);

//Servloger listen:
let server = app.listen(app.get('port'), function() {
    console.log('Listening on port ' + app.get('port'));
});

loginAndRegistration.js 这些是身份验证路由

let express = require('express');
router = express.Router({ mergeParams: true });
User = require("../models/user")

//AUTHENTICATION
let passport = require("passport");
LocalStratergy = require("passport-local");

//PASSPORT CONFIGURATION
app.use(require("express-session")({
    secret: "I wanna go poopie",
    resave: false,
    saveUninitialized: false,
}));
app.use(passport.initialize());
app.use(passport.session());

app.use(function(req,res,next){
  res.locals.currentUser = req.user;
  next();
});
passport.use(new LocalStratergy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

router.get('/login', function(req,res){
    res.render('login');
});

router.post('/login', passport.authenticate('local', {
    successRedirect: "/main",
    failureRedirect: "/login",
}), function(req, res) {
});

router.get('/logout', function(req,res){
    req.logout();
    res.redirect("/");
});

router.get('/register', function(req, res) {
    res.render('register', {});
});


router.post("/register", function(req, res) {
    User.register(new User({ username: req.body.username }), req.body.password, function(error, newlyCreatedUser) {
        if (error) {
            console.log("COULD NOT REGISTER USER IN THE POST ROUTE");
            res.render("register");
            console.log(error);
        } else {
            passport.authenticate("local")(req, res, function() {
                let user = req.body.user;
                newlyCreatedUser.name = user.name;
                newlyCreatedUser.nickname = user.nickname;
                newlyCreatedUser.address = user.address;
                newlyCreatedUser.email = user.email;
                newlyCreatedUser.numberOfDogs = user.numberOfDogs;
                newlyCreatedUser.url = "/user/" + newlyCreatedUser.id;
                newlyCreatedUser.save(function(error, savedUser) {
                    console.log("USER REGISTERED");
                    res.render('maps', {
                        gmapsCredential: credentials.gmaps,
                        'authorized': true
                    });
                });
            });
        }
    });
});

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

module.exports = router;    

我希望能够在我的所有路由中调用isLoggedIn,但我只能在身份验证路由中使用它。如何有选择地将该功能单独导出到我的所有路线?我还希望能够在我的所有.ejs 文件中引用变量currentUser,但它仅适用于与身份验证路由关联的.ejs 文件。如何在我的所有 .ejs 文件中检查 currentUser?

【问题讨论】:

    标签: node.js express authentication passport.js middleware


    【解决方案1】:

    问题的症结在于您的loginAndRegistration.js 文件中隐藏了太多内容。

    首先,如果您想为每条路线运行isLoggedIn,您需要确保首先配置 Passport,即

    app.use(passport.initialize());
    app.use(passport.session());
    
    app.use(function(req,res,next){
      res.locals.currentUser = req.user;
      next();
    });
    passport.use(new LocalStratergy(User.authenticate()));
    passport.serializeUser(User.serializeUser());
    passport.deserializeUser(User.deserializeUser());
    

    需要在配置任何身份验证中间件之前进行设置。这也将解决您的.ejs 问题,因为user 现在将针对每条路线进行序列化,而不仅仅是授权路线。

    最后,您可以在要对其强制身份验证的任何路由之前配置中间件

    app.use(isLoggedIn);
    

    【讨论】:

    • 我不认为 OP 希望所有路由都需要登录,只是一些,但希望能够从所有路由中确定用户是否已登录。
    • @jfriend00 也许是这样,我的回答是基于所问的。在那种情况下就像移动中间件一样简单(我编辑解释)
    猜你喜欢
    • 2021-10-10
    • 1970-01-01
    • 2022-10-21
    • 1970-01-01
    • 2015-06-23
    • 2021-04-03
    • 2019-06-09
    • 2020-02-23
    • 2019-10-05
    相关资源
    最近更新 更多