4

与几乎所有 Web 应用程序一样,我需要一种方法来引用我的 node.js 应用程序中的当前用户。

我的登录/会话系统正常工作,但今天我注意到,当我在一个浏览器中登录我的应用程序并在另一个浏览器中查看它时,我可以看到与在第一个浏览器中看到的相同数据。

我目前将有关当前用户的信息存储在全局 app.current_user 对象中,但我现在意识到这是在所有请求/会话中共享的,因为 node.js 是单线程的——因此,这是一个坏主意。

存储对当前用户的引用的正确方法是什么?当前用户不仅仅是用户数据的哈希,而是一个 Mongoose 模型,所以我想存储在 cookie 中不是一个好主意?

顺便说一句 - 我还存储了用户的设置和其他一些我不想在每次对用户及其设置执行某些操作时再次获取的内容(在单个请求中可能会发生很多次)。我想你可以说我正在将当前用户缓存在内存中。

4

4 回答 4

1

目前存储有关当前用户的信息的正确位置似乎是在请求对象中。

如果您不喜欢将请求对象传递给 mongoose 或其他模块的想法,那么您需要在路由器/控制器/中间件中进行任何更改。例如,我可以在我的操作中为模型设置lastModifiedBy用户 ID 。Postposts_controller update()

您也可以尝试使用相当新的domain功能来存储当前用户数据,但是在使用 Mongoose 时,它​​还没有帮助,因为 Mongoose 还不支持域:https ://github.com/LearnBoost/mongoose/pull/ 1337

于 2013-06-28T06:20:10.240 回答
0

在快递中,您可以使用会话

//To set up session 
app.use(express.cookieParser());
app.use(express.session({secret: 'secret pass', store: sessionStore})); 
//To use it
req.session = {user:name , model:mongo_model};
console.log(req.session.user);

例子

  1. 在这里看一个简单的例子
  2. 在这个问题中查看如何使用 mongostore 获取会话数据
于 2013-03-25T19:43:51.577 回答
0

由于您已经实现了会话,因此在所有路由之前放置一个中间件,该中间件可以找到当前登录的用户并将其存储在 res.locals 中。这使用户数据可用于您可以在应用程序中的任何位置访问的所有路线,如下所示。

else if部分用于记住我的功能。此功能根据是否存在秘密将记住令牌和用户 ID 存储在 cookie 对象/signedCookie 对象中。

app.use(function(req, res, next){
    if (req.session.userId){
        User.findById(req.session.userId, function(err, u){
        res.locals.currentUser = res.locals.currentUser || u
        next()
        })
    }else if (req.signedCookies.userID){ // if the user previously checked remember me
        User.findById(req.signedCookies.userID, function(err, u){
            if (u && u.authenticated(req.signedCookies.rToken, u.rememberDigest)){
                req.session.userId = u._id // re logs in user by resetting session  
                res.locals.currentUser = res.locals.currentUser || u
                next()
            }
        })
    }
})

灵感来自 Micheal Hartl 的 Rails 书

于 2019-05-29T08:13:48.680 回答
0

如果有人像我一样来到这里,寻找传递隐式上下文并使用 express。

我最终为此使用了 express-http-context ( https://www.npmjs.com/package/express-http-context )

从文档:

var express = require('express');
var httpContext = require('express-http-context');
 
var app = express();
// Use any third party middleware that does not need access to the context here, e.g. 
// app.use(some3rdParty.middleware);
app.use(httpContext.middleware);
// all code from here on has access to the same context for each request

获取用户或您想要保留的任何数据:

// Example authorization middleware
app.use((req, res, next) => {
    userService.getUser(req.get('Authorization'), (err, result) => {
        if (err) {
            next(err);
        } else {
            httpContext.set('user', result.user)
            next();
        }
    });
});

在其他需要价值的地方:

var httpContext = require('express-http-context');
 
// Somewhere deep in the Todo Service
function createTodoItem(title, content, callback) {
    var user = httpContext.get('user');
    db.insert({ title, content, userId: user.id }, callback);
}
于 2021-09-21T13:58:47.783 回答