【Express】常用中间件用法:会话管理、输入验证(文章附有完整代码示范)

Express中间件实战:会话与输入验证

前言

Express 是一个简洁而强大的 Node.js Web 应用框架,它提供了丰富的中间件来帮助开发者快速构建 Web 应用。

前面我写的express专栏中很少涉及express中间件的用法,因此现在补充一些常用的中间件。

express专栏-从入门到进阶

本篇文章我们将深入探讨 Express 的两个重要知识点:express-sessionexpress-validator,并展示如何将它们有效地结合起来,以构建一个功能更强大、更安全的 Express 应用。

准备工作

创建和初始化express项目(创建和初始化操作可以看专栏文章)

一、express-session:会话管理

express-session 是一个用于管理会话的中间件,它允许你在不同的请求之间存储和访问用户的会话数据。在用户登录、购物车管理等场景中非常有用。 

安装

npm install express-session

代码示例

在 app.js 中添加以下代码:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

const session = require('express-session');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');



app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 配置 session
app.use(session({
  secret: 'kainama',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: false } // 在生产环境中,建议设置为 true
}));

// 示例路由,设置和获取会话数据
app.get('/set-session', (req, res) => {
  req.session.username = 'JohnDoe';
  res.send('Session set successfully');
});

app.get('/get-session', (req, res) => {
  const username = req.session.username;
  if (username) {
      res.send(`Welcome, ${username}`);
  } else {
      res.send('No session data found');
  }
});

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

测试

使用api测试工具,发送get请求 (设置会话数据)

 发送get请求(获取会话数据)

在上述代码中,我们首先引入了 express-session 并进行了配置。然后创建了两个路由,一个用于设置会话数据,另一个用于获取会话数据。

PS:一定要注意发送顺序,比如你后发送设置会话数据,而先进行获取会话数据,那么肯定是获取不到username的值。

二、express-validator:输入验证

express-validator 是一个用于验证和清理用户输入的中间件,它可以帮助你防止恶意输入和数据损坏。

安装

npm install express-validator

代码示例

在 app.js 中添加以下代码:

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

const { check, validationResult } = require('express-validator');
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');



app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));


// 示例路由,验证用户输入
app.post('/validate', [
  check('email').isEmail().withMessage('Invalid email'),
  check('password').isLength({ min: 6 }).withMessage('Password must be at least 6 characters')
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
  }
  res.send('Input validated successfully');
});
app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

 比如这里我们设置是对email和password进行了数据验证

  • email:需要满足邮箱格式
  • password:不小于6位

  代码语句分析

check('email').isEmail().withMessage('Invalid email')

1. check('email')

  • check 是 express-validator 库提供的一个函数,它的作用是指定要验证的字段。
  • 'email' 是要验证的字段名,通常是表单中的一个输入字段名或者请求体中的一个属性名。在处理 HTTP 请求时,check 函数会从请求体、查询字符串、URL 参数等位置查找名为 email 的字段。

2. .isEmail()

  • 这是一个验证器方法,它是 check 函数返回的验证对象的一个方法。
  • isEmail() 用于验证 email 字段的值是否符合电子邮件地址的格式。它会检查输入是否包含有效的用户名、域名和顶级域名,例如 user@example.com 是有效的,而 userexample.com 是无效的。

3. .withMessage('Invalid email')

  • withMessage 方法用于为验证失败的情况提供自定义的错误消息。
  • 当 isEmail() 验证失败时,会生成一个包含错误信息的对象,这个错误信息就是 'Invalid email'。在后续处理验证结果时,可以使用这个错误信息来给用户反馈具体的错误原因。

 测试

错误的email格式

返回的结果

错误的密码格式 

返回的结果 

 email和密码均不符合验证

 

正确的验证格式

三、结合使用的案例

创建一个简单的用户登录系统。在这个系统中,用户需要输入有效的电子邮件和密码进行登录,登录成功后会将用户信息存储在会话中,后续可以通过会话检查用户是否已登录。

代码示范

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

const session = require('express-session');
const { check, validationResult } = require('express-validator');
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');



app.use(logger('dev'));
app.use(express.json());
// app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 配置 session
app.use(session({
  secret: 'kainama',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: false } // 在生产环境中,建议设置为 true
}));

// 解析表单数据
app.use(express.urlencoded({ extended: true }));

// 模拟用户数据库
const users = [
  { email: 'test@qq.com', password: 'root123' }
];

// 登录页面
app.get('/login', (req, res) => {
  res.send(`
      <form method="post" action="/login">
          <label for="email">Email:</label>
          <input type="email" id="email" name="email" required><br>
          <label for="password">Password:</label>
          <input type="password" id="password" name="password" required><br>
          <button type="submit">Login</button>
      </form>
  `);
});
// 处理登录请求
app.post('/login', [
  // 验证电子邮件
  check('email')
     .isEmail()
     .withMessage('Please enter a valid email address'),
  // 验证密码长度
  check('password')
     .isLength({ min: 6 })
     .withMessage('Password must be at least 6 characters long')
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
  }

  const { email, password } = req.body;
  const user = users.find(u => u.email === email && u.password === password);

  if (user) {
      // 登录成功,将用户信息存储在会话中
      req.session.user = user;
      res.send('Login successful!');
  } else {
      res.status(401).send('Invalid email or password');
  }
});
// 受保护的路由,需要登录才能访问
app.get('/dashboard', (req, res) => {
  const user = req.session.user;
  if (user) {
      res.send(`Welcome to the dashboard, ${user.email}!`);
  } else {
      res.status(401).send('Please log in to access this page');
  }
});

// 注销路由
app.get('/logout', (req, res) => {
  req.session.destroy((err) => {
      if (err) {
          console.error(err);
      }
      res.send('Logged out successfully');
  });
});

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

 启动服务,访问http://localhost:3000/login

测试

使用测试的账号密码

 

 访问受保护的路由

 

大家可以自行测试登录失败未登录前访问受保护路由的情况。 

四、小结

 通过结合使用 express-sessionexpress-validator ,我们可以构建一个功能更强大、更安全的 Express 应用。express-session 帮助我们管理用户会话,express-validator 确保用户输入的有效性。这些中间件的组合可以大大提高开发效率和应用的安全性。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十八朵郁金香

感恩前行路上有你相伴

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值