NodeJS,在路由中获取登录用户的用户名

Posted

技术标签:

【中文标题】NodeJS,在路由中获取登录用户的用户名【英文标题】:NodeJS, getting username of logged in user within route 【发布时间】:2018-12-04 01:21:57 【问题描述】:

我正在学习 NodeJS,并按照一些视频教程来制作东西,以了解 NodeJS 和 Express。由于几乎没有解释,它更多地变成了复制,所以尝试用我学到的东西制作我自己的东西等等。

使用 PassportJS、ExpressJs 和 Mongoose 制作一个简单的登录功能。 登录名和东西有效,如果我在主 app.js 中使用以下方法定义它,我可以获得当前登录用户的用户名并显示它:

app.get("/stuff", (req,res) => 
    res.render("stuff.html", username:req.user.username);
);

现在,如果我想通过使用路由器变得更好和结构化,我无法让它工作。它会抛出错误,说 username 未定义,使页面无法呈现。如果我不传递任何变量或使用我知道会起作用的变量(例如var x = "Hello"; res.render … msg:x);),路由器本身就会起作用。

处理路由的app.js 的一部分:

var stuff = require("./routes/stuff");
app.use("/stuff", stuff);

module.exports.app;

我已经尝试cont x = require("…") 基本上是 app.js 在这个 stuff.js 文件中的所有内容,但无济于事,因此删除了除 express + 路线之外的所有内容以重新开始。

如何将app.js 中的用户名传递给路由文件?如果可能,最好使用app.get("*")… 或其他方式自动处理每个页面。

整个stuff.js:

/* Routes */
const express = require("express");
const router = express.Router();

/* Stuff */
router.get("/", function(req, res, next) 
    res.render("stuff.html", username:req.user.username);
    console.log(req.user.username);
    next();
);

/* Bottom */
module.exports = router;

app.js的登录部分:

app.post('/login',
    passport.authenticate('local', 
        
            successRedirect: '/dashboard',
            failureRedirect: '/login',
            failureFlash: 'Wrong login'
        
), function(req,res) 
        console.log("Hello " + req.user.username);
);

passport.serializeUser(function(user,done) 
    done(null, user.id);
);
passport.deserializeUser(function(id,done) 
    User.getUserById(id, function(err, user) 
        done(err,user);
    );
);

passport.use(new LocalStrategy(function(username,password,callback) 
    User.getUserByUsername(username, function(err,user) 
        if(err) throw err;
        if(!user) 
            return callback(null, false, msg: "shit");
        

        User.comparePassword(password, user.password, function(err,isMatch) 
            if(err) return callback(err);
            if(isMatch) 
                return callback(null, user);
             else 
                return callback(null, false, msg:"Something");
            
        );
    );
));

用于处理注册新用户的users.js 文件(如果相关):

const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/users");
const db = mongoose.connection;
mongoose.Promise = global.Promise;
const bcrypt = require("bcryptjs");

/* Data schema */
const userSchema = mongoose.Schema(
    name: 
        type: String
    ,
    username: 
        type: String,
        index: true
    ,
    password: 
        type: String
    ,
    email: 
        type: String
    
);

var User = module.exports = mongoose.model("User", userSchema);

module.exports.createUser = function(newUser, callback) 
    bcrypt.genSalt(10, function(err, salt) 
        bcrypt.hash(newUser.password, salt, function(err, hash) 
            newUser.password = hash;
            newUser.save(callback);
        );
    );


module.exports.getUserById = function(id, callback) 
    User.findById(id, callback);


module.exports.getUserByUsername = function(username, callback) 
    var query = username: username;
    User.findOne(query, callback);


module.exports.comparePassword = function(testPw, hash, callback) 
    bcrypt.compare(testPw, hash, function(err,isMatch) 
            callback(null,isMatch);
    );

【问题讨论】:

【参考方案1】:

据我了解,您正在尝试将您的用户名传递给最好的每个文件,包括您的路由器文件。我为此做了什么来使用 app.js 中的中间件来传递每个页面。或者您也可以简单地在其他页面中实现护照实施,我猜这可能没用。

app.use(function(req,res,next)
  res.locals.currentUser=req.user
  next()

然后,您可以在尝试渲染时在每个页面中使用您的 currentUser。

【讨论】:

【参考方案2】:

我遇到了同样的问题,可能是在遵循相同的教程之后...... 我发现你在app.js中需要的功能是:

app.get('*', function(req, res,next)
    res.locals.user = req.user || null;
    next();
)

它应该已经在 app.js 中了。现在,在所有其他页面中,您应该可以使用 req.user.username

【讨论】:

以上是关于NodeJS,在路由中获取登录用户的用户名的主要内容,如果未能解决你的问题,请参考以下文章

如何在 NodeJS 中获取 Instagram 用户名和访问令牌

用户登录后路由到用户帐户

登录页面不会重定向到路由到登录页面

如何在 NodeJS 中使用 JWT 令牌验证路由

我们如何分离管理员和用户的路线?

如何从 JWT 标头中获取值到 nodejs 中的变量中?