【问题标题】:How to implement session with express-session?如何使用 express-session 实现会话?
【发布时间】:2018-12-14 11:15:32
【问题描述】:

我正在考虑在我的 node.js 应用程序中使用 session。

我了解以下内容: - session-cookie 使用cookie在客户端保存会话数据 - express-session 使用 cookie 存储 sessionID,所有 session 数据都存储在服务器端

我担心安全性,所以我会选择 express-session。 但是文档说默认情况下快速会话将数据存储在内存中,这在生产中是不可想象的。

所以我的问题是: 你如何在你的应用程序中实现会话? 会话存储不会影响性能吗? 如果没有,你会推荐我哪个会话商店? (我的应用程序使用 MySql 作为数据库)

非常感谢您的帮助。 问候。

【问题讨论】:

  • 大概您还没有完整阅读express-session 文档?好像你有,你会遇到compatible stores 部分并发现express-mysql-session
  • 我确实找到了 express-mysql-session 模块,但我也发现使用数据库存储会话可能会出现问题...我没有使用任何集群应用程序,所以文件存储方法可能有效吗?
  • 这是您应该在问题中说明的信息类型。因此,如果您不想将状态存储在数据库中,那么您想将它存储在哪里?我很感兴趣...
  • 是的,你是对的,第一个问题很抱歉。我有点困惑。我认为使用存储与应用程序相关的所有数据的 mysql 数据库会影响应用程序的性能。但是既然你提出了这个解决方案,我现在假设它不会影响性能。 (我在之前的评论中指的是 Redis 或 MongoDB,但只有一个数据库应该更易于管理)我将开始研究 express-mysql-session!

标签: mysql node.js session-cookies express-session session-store


【解决方案1】:

我发现管理会话数据的最简单方法是令牌。

您可以轻松地为 expressjs 和 nodejs 使用“护照”。

您可以生成一个令牌,该令牌使用私钥在您的 NodeJS 后端进行签名,并且可以通过公钥进行识别。这些令牌甚至可以被撤销。

它们作为网络标准传递到“授权”标头中。

这是我用于提取和检查用户提供的生成令牌的验证示例。

module.exports.ensureAuthorized = function ensureAuthorized(req, res) {
    return new Promise((resolve) => {
        let bearerToken;
        let bearerHeader = req.headers["authorization"];
        if (typeof bearerHeader !== 'undefined') {
            let bearer = bearerHeader.split(" ");
            bearerToken = bearer[1];
            req.token = bearerToken;
            this.userPayload(req.token).then((result) => {
                if (!result) {
                    return res.status(403).json({message:"Failed to verify token supplied in authorization header", data: null});
                }else{
                    resolve(result);
                }
            });
        } else {
            return res.status(403).json({message:"Failed to supply token in authorization header.", data: null});
        }
    });
};

这是我对尝试登录的用户的 REST API 调用:(生成有效令牌)

let jwt = require('jsonwebtoken');
let config = require('../../misc/config');
global.atob = require("atob");
let mongoose = require('mongoose');

exports.getLogin = function(req, res) {
    const btoaAuth = (req.headers.authorization || '').split(' ')[1] || '';
    const [username, password, rememberMe] = atob(btoaAuth).toString().split(':');
    if(username && password) {
        usersModel.findOneAndUpdate({username: username},{lastLogin: new Date(),})
            .exec(function (err, userResult) {
                if(err) return res.status(500).json({message: "Server failed search users", data: err});
                if(!userResult) return res.status(500).json({message: "Username invalid", data: err});
                userResult.verifyPassword(password, function(err, isMatch) {
                    if (err) {  return res.status(500).json({message: "Server failed to process user login", data: err});}

                    // Password did not match
                    if (!isMatch) {  return res.status(403).json({message: "Password incorrect", data: err}); }
                    // Success
                    let token = jwt.sign({_id: userResult._id,username: userResult.username, exp: rememberMe === 'true'? Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 365 * 100) : Math.floor(Date.now() / 1000) + (60 * 60) }, config.jwtSecret);
                    let obj = {};
                    obj['profile'] = userResult;
                    obj['profile']['password'] = undefined;
                    obj['token'] = token;
                    return res.status(200).json({message: "Successful login", data: obj});
                });
            });
    }else{
        return res.status(400).json({message: "Username and password are required", data: req.body});
    }
};

【讨论】:

  • 老实说,我不知道从哪里开始这段代码 - 无法解析的 Promise,返回不正确的状态代码并将内部信息泄露给客户端 :( 我希望你没有在已部署的生产环境中运行它.
  • 感谢您的回复。我宁愿不使用令牌。
猜你喜欢
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 2018-10-03
  • 2015-05-18
  • 2018-06-30
  • 2018-10-10
  • 1970-01-01
相关资源
最近更新 更多