Sequelize 实践:实现用户身份认证与授权

在现代 Web 应用程序中,用户身份认证和授权是非常重要的功能。Sequelize 是一个使用 Node.js 编写的 ORM(对象关系映射)工具,可以让我们更容易地操作数据库。在本文中,我们将使用 Sequelize 实现用户身份认证和授权的功能。

准备工作

在开始本文之前,我们需要准备一些东西:

  1. 安装 Node.js 和 npm。
  2. 安装 MySQL 数据库和 MySQL Workbench。
  3. 创建一个空的 Node.js 项目,并安装 Sequelize 和相关依赖。
npm install --save sequelize mysql2 bcrypt jsonwebtoken

创建用户模型

首先,我们需要创建一个用户模型来存储用户信息。在 Sequelize 中,我们可以使用 sequelize.define() 方法来定义一个模型。

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('mysql://user:password@localhost:3306/database');

const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  username: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true,
  },
  password: {
    type: DataTypes.STRING,
    allowNull: false,
  },
});

在上面的代码中,我们定义了一个名为 User 的模型,并指定了三个字段:idusernamepassword。其中,id 是自增的主键,username 是唯一的用户名,password 是用户的密码。

添加用户注册功能

接下来,我们需要添加用户注册功能。在注册过程中,我们需要对用户密码进行加密,以保证用户数据的安全性。在 Node.js 中,我们可以使用 bcrypt 库来进行密码加密。

const bcrypt = require('bcrypt');

// 注册用户
async function registerUser(username, password) {
  // 加密密码
  const hashedPassword = await bcrypt.hash(password, 10);

  // 创建用户
  const user = await User.create({
    username,
    password: hashedPassword,
  });

  return user;
}

在上面的代码中,我们使用 bcrypt.hash() 方法对用户密码进行加密,并将加密后的密码保存到数据库中。注意,我们使用 await 关键字来等待异步操作完成。

添加用户登录功能

接下来,我们需要添加用户登录功能。在登录过程中,我们需要检查用户输入的密码是否与数据库中保存的密码一致。在 Node.js 中,我们可以使用 bcrypt.compare() 方法来进行密码比较。

const jwt = require('jsonwebtoken');

// 登录用户
async function loginUser(username, password) {
  // 查找用户
  const user = await User.findOne({ where: { username } });

  if (!user) {
    throw new Error('Invalid username');
  }

  // 比较密码
  const isPasswordValid = await bcrypt.compare(password, user.password);

  if (!isPasswordValid) {
    throw new Error('Invalid password');
  }

  // 生成 token
  const token = jwt.sign({ id: user.id }, 'secret');

  return { user, token };
}

在上面的代码中,我们使用 User.findOne() 方法查找用户,并使用 bcrypt.compare() 方法比较密码。如果密码不匹配,则抛出错误。如果密码匹配,则使用 jsonwebtoken 库生成一个 token,并将用户和 token 返回。

添加路由和授权中间件

最后,我们需要添加路由和授权中间件来实现用户身份认证和授权的功能。

const express = require('express');
const app = express();

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

  try {
    const user = await registerUser(username, password);
    res.json(user);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

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

  try {
    const { user, token } = await loginUser(username, password);
    res.json({ user, token });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

// 授权中间件
function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];

  if (!token) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  try {
    const decoded = jwt.verify(token, 'secret');
    req.userId = decoded.id;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Unauthorized' });
  }
}

// 受保护的路由
app.get('/protected', authMiddleware, async (req, res) => {
  const user = await User.findByPk(req.userId);
  res.json(user);
});

app.listen(3000, () => console.log('Server started'));

在上面的代码中,我们定义了两个路由:/register/login。分别用于用户注册和用户登录。我们还定义了一个授权中间件 authMiddleware,用于验证用户的 token。最后,我们定义了一个受保护的路由 /protected,只有经过授权的用户才能访问。

总结

在本文中,我们使用 Sequelize 实现了用户身份认证和授权的功能。我们创建了一个用户模型,并使用 bcrypt 库对用户密码进行加密。我们还使用 jsonwebtoken 库生成了一个 token,用于验证用户的身份。最后,我们实现了一个授权中间件,用于验证用户的 token,并实现了一个受保护的路由,只有经过授权的用户才能访问。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658d4fafeb4cecbf2d3443ff


纠错
反馈