使用 express-session 和 connect-mongo 将会话数据存储在 MongoDB示例及实现用户登录会话示例

express-session 是 Express 框架的一个中间件,用于处理会话数据。而 connect-mongo 是一个将 express-session 的会话数据存储在 MongoDB 中的第三方库。通过 connect-mongo,你可以轻松地将用户会话持久化到 MongoDB 数据库中,这对于需要跨多个请求或服务器实例保持用户状态的应用非常有用。

一、下面是一个使用 express-sessionconnect-mongo 将会话数据存储在 MongoDB 中的示例:

  1. 安装依赖

    首先,你需要安装 expressexpress-sessionconnect-mongo

    npm install express express-session connect-mongo mongoose
    

    注意:虽然 connect-mongo 不直接依赖于 mongoose,但使用 mongoose 可以帮助你更方便地管理 MongoDB 连接。然而,在这个示例中,我们将直接使用 connect-mongo 提供的 MongoDB 连接选项。

  2. 配置 Express 应用

    接下来,在你的 Express 应用中配置 express-sessionconnect-mongo

    const express = require('express');
    const session = require('express-session');
    const MongoStore = require('connect-mongo')(session);
    const mongoose = require('mongoose');
    
    const app = express();
    
    // 连接到 MongoDB 数据库
    mongoose.connect('mongodb://localhost:27017/mydatabase', {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      // 如果你使用的是 MongoDB Atlas 或其他需要认证的 MongoDB 服务,
      // 你可能还需要提供用户名和密码,如下所示:
      // auth: { user: 'yourUsername', password: 'yourPassword' }
    });
    
    mongoose.connection.once('open', () => {
      console.log('Connected to MongoDB');
    });
    
    const mongoStoreOptions = {
      mongooseConnection: mongoose.connection,
      collection: 'sessions', // 会话数据将存储在这个集合中
      ttl: 24 * 60 * 60, // 会话在 MongoDB 中的存活时间(秒),这里设置为1天
      autoCommit: false, // 如果设置为true,则每次请求都会自动提交会话更改(可能会增加数据库负载)
      autoRemove: 'interval', // 自动清理过期会话的策略,'interval'表示按时间间隔清理
      autoRemoveInterval: 10 // 自动清理过期会话的时间间隔(分钟)
    };
    
    const mongoStoreInstance = new MongoStore(mongoStoreOptions);
    
    app.use(session({
      secret: 'your_secret_key', // 用于签名会话ID cookie的密钥
      resave: false, // 强制将会话保存回会话存储,即使会话没有更改
      saveUninitialized: false, // 强制将未初始化的会话保存到存储中
      store: mongoStoreInstance, // 使用 MongoDB 存储会话
      cookie: {
        secure: false, // 如果你的应用通过 HTTPS 提供服务,则应该设置为 true
        httpOnly: true, // 阻止客户端 JavaScript 访问 cookie
        maxAge: 24 * 60 * 60 * 1000, // cookie 的存活时间(毫秒),这里也设置为1天
      },
    }));
    
    // 示例路由
    app.get('/', (req, res) => {
      if (req.session.views) {
        req.session.views++;
        res.send(`You have visited this page ${req.session.views} times`);
      } else {
        req.session.views = 1;
        res.send('Welcome to the session demo. Refresh!');
      }
    });
    
    app.listen(3000, () => {
      console.log('Server is running on port 3000');
    });
    
  3. 运行应用

    确保你的 MongoDB 实例正在运行,并且你已经在上面配置的数据库中创建了必要的集合(虽然 connect-mongo 会在需要时自动创建集合)。然后运行你的 Express 应用。

    node app.js
    

    现在,当你访问 http://localhost:3000 时,express-session 会使用 connect-mongo 和 MongoDB 来存储会话数据。每次你刷新页面时,会话中的 views 计数器都会增加。

注意事项

  • 在生产环境中,你应该通过 HTTPS 提供你的应用,并将 cookie.secure 设置为 true,以确保会话 cookie 的安全性。
  • secret 应该是一个足够复杂且难以猜测的字符串,以确保会话 ID 的签名安全性。
  • 你可以根据需要调整会话的过期时间和其他配置选项。
  • 确保你的 MongoDB 数据库连接字符串和其他配置信息是正确的,并且你的数据库实例是可访问的。
  • 如果你使用的是 MongoDB Atlas 或其他需要认证的 MongoDB 服务,请确保提供了正确的认证信息。

二、下面是一个使用 express-sessionconnect-mongo 实现用户登录会话的简单示例:

这个示例将展示如何设置会话中间件、处理用户登录请求,并在会话中存储用户信息。

首先,确保你已经安装了必要的依赖:

npm install express express-session connect-mongo mongoose body-parser

然后,创建一个 Express 应用,并配置会话中间件和用户登录逻辑:

const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

const app = express();

// MongoDB 连接配置
mongoose.connect('mongodb://localhost:27017/mydatabase', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

mongoose.connection.once('open', () => {
  console.log('Connected to MongoDB');
});

// 会话存储配置
const mongoStoreOptions = {
  mongooseConnection: mongoose.connection,
  collection: 'sessions',
  ttl: 24 * 60 * 60, // 会话在 MongoDB 中的存活时间(秒)
};

const mongoStoreInstance = new MongoStore(mongoStoreOptions);

// 会话中间件配置
app.use(session({
  secret: 'your_secret_key', // 用于签名会话ID cookie的密钥
  resave: false,
  saveUninitialized: false,
  store: mongoStoreInstance,
  cookie: {
    secure: false, // 在生产环境中应设置为 true(通过 HTTPS 提供服务)
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000, // cookie 的存活时间(毫秒)
  },
}));

// 解析 JSON 请求体
app.use(bodyParser.json());

// 示例用户模型(仅用于演示,实际中应使用更复杂的用户验证和存储逻辑)
const UserSchema = new mongoose.Schema({
  username: String,
  password: String, // 注意:在生产环境中,密码应加密存储
});

const User = mongoose.model('User', UserSchema);

// 用户登录路由
app.post('/login', async (req, res) => {
  const { username, password } = req.body;

  // 在这里执行用户验证逻辑(例如,查询数据库并比较密码)
  // 注意:这个示例中的密码验证是非常不安全的,仅用于演示
  const user = await User.findOne({ username, password });

  if (user) {
    // 验证成功,将用户信息存储在会话中
    req.session.user = { username: user.username };
    res.send({ message: 'Login successful', user: req.session.user });
  } else {
    // 验证失败,返回错误消息
    res.status(401).send({ message: 'Invalid username or password' });
  }
});

// 受保护的路由示例
app.get('/protected', (req, res) => {
  if (req.session.user) {
    // 用户已登录,返回受保护的内容
    res.send({ message: 'Welcome to the protected route', user: req.session.user });
  } else {
    // 用户未登录,重定向到登录页面或返回错误消息
    res.status(403).send({ message: 'You are not authorized to access this route' });
  }
});

// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

注意事项

  1. 安全性:上述示例中的密码验证是非常不安全的,因为它直接将明文密码与数据库中的密码进行比较。在实际应用中,你应该使用密码哈希和加盐技术来存储和验证密码。

  2. HTTPS:在生产环境中,你应该通过 HTTPS 提供你的应用,并将 cookie.secure 设置为 true,以确保会话 cookie 的安全性。

  3. 用户模型:上述示例中的用户模型非常简单,仅包含用户名和密码。在实际应用中,你可能需要更复杂的用户模型,包括额外的字段(如电子邮件、电话号码、角色等)以及更复杂的验证逻辑。

  4. 会话过期:你可以根据需要调整会话的过期时间(ttl)和其他配置选项。

  5. 错误处理:上述示例中的错误处理非常简单。在实际应用中,你应该有更完善的错误处理机制来处理各种可能的异常情况。

  6. 数据库连接:确保你的 MongoDB 数据库连接字符串和其他配置信息是正确的,并且你的数据库实例是可访问的。如果使用的是 MongoDB Atlas 或其他需要认证的 MongoDB 服务,请确保提供了正确的认证信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值