教程 express tutorial

实现登录系统

在 Web 应用中,用户登录系统是大多数应用的基本需求。一个完整的登录系统包括用户身份验证、会话管理、登录状态保持等功能。使用 Express 可以快速构建一个简单的登录系统。在本章节中,我们将展示如何在 Express 中实现一个基本的登录系统,并利用 Session 或 Cookie 来保持用户的登录状态。

步骤概览

  1. 创建用户注册和登录接口。
  2. 使用 Session 管理用户登录状态。
  3. 保护需要认证的路由,确保用户登录后才能访问。
  4. 提供退出登录的功能。

1. 设置 Express 项目

首先,我们需要搭建一个基本的 Express 项目,并安装需要的依赖:

bash
npm init -y
npm install express express-session body-parser

`

接着,创建一个基本的 Express 应用:

js
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');

const app = express();
const port = 3000;

// 使用 body-parser 解析 POST 请求的表单数据
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 使用 session 来管理用户登录状态
app.use(session({
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: false }  // 开发环境设置为 false
}));

// 用户数据库模拟
const users = [
  { username: 'john_doe', password: 'password123' },
  { username: 'jane_doe', password: '12345' }
];

app.listen(port, () => {
  console.log(`Server is running at http://localhost:${port}`);
});

2. 用户注册与登录

2.1 用户注册

在实际项目中,用户的注册需要将用户数据存储到数据库中。在本示例中,我们通过一个简单的内存数组来模拟数据库。用户注册时,我们会检查用户名是否已经存在,如果不存在则将用户添加到“数据库”中。

js
app.post('/register', (req, res) => {
  const { username, password } = req.body;

  // 检查用户名是否已经存在
  const userExists = users.some(user => user.username === username);
  if (userExists) {
    return res.status(400).send('用户名已存在');
  }

  // 将新用户添加到 "数据库" 中
  users.push({ username, password });
  res.send('注册成功');
});

2.2 用户登录

用户登录时,我们需要验证其用户名和密码。如果验证成功,我们会将用户的登录状态存储在 Session 中,以便后续请求可以识别该用户。

js
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // 查找匹配的用户
  const user = users.find(u => u.username === username && u.password === password);
  if (!user) {
    return res.status(401).send('用户名或密码错误');
  }

  // 登录成功,将用户信息存储在 session 中
  req.session.user = user;
  res.send('登录成功');
});

3. 保护需要认证的路由

为了确保用户在登录后才能访问某些敏感页面或操作,我们需要在相关路由上加上认证中间件。这个中间件会检查 Session 中是否存有用户数据,如果没有,则返回未授权的错误。

js
// 认证中间件
function isAuthenticated(req, res, next) {
  if (req.session.user) {
    return next();  // 用户已登录,继续执行下一个中间件
  }
  res.status(403).send('未授权访问');
}

// 保护需要认证的路由
app.get('/dashboard', isAuthenticated, (req, res) => {
  res.send(`欢迎回来,${req.session.user.username}`);
});

在上面的代码中,isAuthenticated 中间件会检查用户是否已经登录(即 req.session.user 是否存在)。如果用户没有登录,它会返回一个 403 错误。

4. 退出登录

退出登录的功能通常是通过销毁当前用户的 Session 实现的。当用户点击退出时,Session 将被销毁,用户将无法访问受保护的页面。

js
app.get('/logout', (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      return res.status(500).send('退出登录失败');
    }
    res.send('退出登录成功');
  });
});

在这段代码中,req.session.destroy() 会销毁当前用户的会话,用户将被退出。

5. 完整代码示例

以下是完整的 Express 应用代码,实现了用户注册、登录、退出以及保护的功能:

js
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');

const app = express();
const port = 3000;

// 使用 body-parser 解析 POST 请求的表单数据
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 使用 session 来管理用户登录状态
app.use(session({
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: false }  // 开发环境设置为 false
}));

// 用户数据库模拟
const users = [
  { username: 'john_doe', password: 'password123' },
  { username: 'jane_doe', password: '12345' }
];

// 认证中间件
function isAuthenticated(req, res, next) {
  if (req.session.user) {
    return next();  // 用户已登录,继续执行下一个中间件
  }
  res.status(403).send('未授权访问');
}

// 注册路由
app.post('/register', (req, res) => {
  const { username, password } = req.body;

  const userExists = users.some(user => user.username === username);
  if (userExists) {
    return res.status(400).send('用户名已存在');
  }

  users.push({ username, password });
  res.send('注册成功');
});

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

  const user = users.find(u => u.username === username && u.password === password);
  if (!user) {
    return res.status(401).send('用户名或密码错误');
  }

  req.session.user = user;
  res.send('登录成功');
});

// 保护的路由
app.get('/dashboard', isAuthenticated, (req, res) => {
  res.send(`欢迎回来,${req.session.user.username}`);
});

// 退出登录
app.get('/logout', (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      return res.status(500).send('退出登录失败');
    }
    res.send('退出登录成功');
  });
});

app.listen(port, () => {
  console.log(`Server is running at http://localhost:${port}`);
});

总结

本章节介绍了如何在 Express 中实现一个简单的登录系统,包含以下主要步骤:

  1. 用户注册与登录:通过 POST 请求接收用户提交的表单数据并验证,成功登录后将用户信息存储在 Session 中。
  2. 保护路由:使用中间件保护需要用户认证才能访问的路由,确保只有登录用户才能访问这些路由。
  3. 退出登录:销毁用户的 Session,使其退出登录状态。

通过这种方式,我们可以轻松实现一个基于 Session 的用户登录系统,并且可以根据实际需求扩展更多功能。