目录
- 1 创建数据库
- 2 连接数据库
- 3 集成ORM库
- 4 创建业务逻辑
- 5 创建路由
- 7 测试接口
- 总结
我们在编写后端接口的时候操作数据库是一种常见的功能需求,express本身并不提供直接操作数据库的能力,需要借助第三方库来操作数据库,本篇讲解一下软件开发中像登录和注册如何实现。
1 创建数据库
通常我们编制软件的时候需要选择数据库,我这里选择mysql作为示例,如果你有比较喜欢的数据库也可以按照相同的操作进行。
安装数据库可以参考网上的教程,因为比较普遍这里就不赘述了。数据库安装好之后,用数据库的连接工具来操作数据,我这里用的是navicate,你也可以用别的。
打开我们的navicate,点击连接
选择mysql
输入连接名,因为我数据库是在本地,直接输入localhost就行,然后输入数据库的用户名和密码,点击测试连接
然后点击你的连接名,右键,点击新建数据库
输入数据库的名称,字符集选择utf8mb4,排序规则选择第一项就可以
双击数据库名称,选择表,点击新建表
创建四个字段,分别是username、password、email、id,前三个选择varchar类型就可以,第四个字段需要作为主键,勾选自动增长
然后点击保存按钮,输入表名即可
除了可视化的建表外,我们还可以使用sql语句来建表,以下是建表语句
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
还是在navicate里,点击查询、新建查询,输入我们的建表语句
点击运行,看到输出的OK就表示表已经创建成功了
2 连接数据库
连接数据库通常需要配置数据库的IP、用户名和密码,我们创建一个环境变量的配置文件来存储这些信息,打开我们的工程,在根目录下创建一个.env的文件
贴入如下配置
DATABASE_NAME=express
DATABASE_USER=root
DATABASE_PASSWORD=111111
DATABASE_HOST=localhost
具体的配置信息要改成你自己设定的数据库的信息
然后在app.js中读取我们的配置
require('dotenv').config();//加载环境变量
我们使用了dotenv的库,需要先进行安装
npm install dotenv
完成上述步骤你就可以看到我们的配置信息被正确的读取到了
3 集成ORM库
我们这里使用sequelize来做数据库的操作,orm的好处可以屏蔽具体的数据库语句的细节,在操作数据库的时候可以使用他封装好的API,省了不少事。而且后期如果你想切换数据库,改一下配置文件就可以了。
在项目的根目录创建一个config文件夹,里边创建一个database.js
贴入如下的配置信息
// 导入 Sequelize 和相应的数据库驱动
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize(process.env.DATABASE_NAME, process.env.DATABASE_USER, process.env.DATABASE_PASSWORD, {
host: 'localhost',
dialect: 'mysql', // 根据你的数据库类型选择 'mysql' | 'mariadb' | 'postgres' | 'mssql' | 'sqlite' | 'postgres-native' | 'mariadb-native'
// 其他可能的配置选项
dialectOptions: {
useUTC: true, // 对于不支持 UTC 的数据库,启用这个选项
// 针对特定数据库的额外配置,比如 SSL
},
pool: {
max: 5, // 连接池中的最大连接数
min: 0, // 连接池中的最小连接数
acquire: 30000, // 连接最大等待时间(毫秒)
idle: 10000 // 连接在释放之前可以空闲的最长时间(毫秒)
},
// 其他的 Sequelize 配置项...
logging: console.log, // 启用日志,你可以选择自己的日志函数或者禁用它
});
// 测试连接
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
// 导出 Sequelize 实例供其他模块使用
module.exports = sequelize;
添加配置信息后我们先需要按照库,执行如下命令
npm install sequelize
npm install mysql2
配置创建好之后,需要创建模型层,新建一个model文件夹,里边创建一个User.js
输入如下配置
// models/User.js
const { Sequelize, Model } = require('sequelize');
const sequelize = require('../config/database'); // 假设你有一个数据库配置文件
class User extends Model {}
User.init(
{
email: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
username: {
type:Sequelize.STRING,
allowNull: false,
}
// 其他字段...
},
{
sequelize,
modelName: 'User',
}
);
module.exports = User;
如果你的模型和表名不一致,需要指定表名,我这里使用了默认的推断机制,他会转换为小写加一个s的后缀去匹配表,正好是我们的users表
4 创建业务逻辑
我们把业务逻辑封装到service层,这样代码的维护性要好一点,在根目录创建services文件夹,创建一个authService.js
// services/authService.js
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
class AuthService {
async signUp(username, password,email) {
console.log(username,password,email)
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
const user = await User.create({ username,email, password: hashedPassword });
return user;
}
async signIn(username, password) {
const user = await User.findOne({ where: { username } });
if (!user) throw new Error('User not found');
const isMatch = await bcrypt.compare(password, user.password);
console.log("isMatch",isMatch)
if (!isMatch) throw new Error('Invalid credentials');
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET_KEY, { expiresIn: '1h' });
return { user, token };
}
}
module.exports = AuthService;
这里我们写了两个方法,一个是注册,注册的时候需要给密码加密,登录的时候需要返回给用户一个token,需要安装需要的第三方的库
npm install bcrypt jsonwebtoken
因为我们在创建token时候需要一个密钥,我们也在配置信息里添加,在.env里增加密钥
JWT_SECRET_KEY=d6b522d9a989a9ff8494676b4e1592ea58488b8a4f8126d33d331604e769f4d3
5 创建路由
一切准备就绪之后最后一步就是创建路由了,我们在根目录创建routes,然后创建auth.js
输入如下代码
// routes/auth.js
const express = require('express');
const router = express.Router();
const AuthService = require('../services/authService');
const authService = new AuthService();
// 登录路由
router.post('/signIn', async (req, res, next) => {
try {
const { username, password } = req.body;
console.log(username,password)
console.log(authService)
const { user, token } = await authService.signIn(username, password);
res.cookie('token', token, { httpOnly: true, secure: true }); // 假设使用cookie存储token
return res.status(200).json({ code:200,data:{token:token},message:'login success' });
} catch (error) {
console.log('error',error.message)
if (error.message === 'Invalid credentials'||error.message ==='User not found') {
// 如果是因为无效的凭证,返回401状态码
res.status(401).json({ code:401,message: 'Invalid credentials' });
} else {
// 其他错误,返回500状态码
res.status(500).json({ code:500,message: 'Internal server error' });
// 可能还需要记录错误日志
}
//next(error);
}
});
// 注册路由
router.post('/signUp', async (req, res, next) => {
try {
const { username, password ,email} = req.body;
const user = await authService.signUp(username,password,email);
res.status(200).json({code:200,id:user.id});
} catch (error) {
//next(error);
res.status(500).json({ code:500,message: 'Internal server error' });
}
});
module.exports = router;
我们的路由创建好之后要挂载到应用程序里,修改app.js增加路由的挂载代码
const authRouter = require('./routes/auth')//引入权限接口路由
app.use('/api/auth', authRouter);//挂载权限路由
因为接口涉及到参数解析,我们还要启用解析的中间件
// 对于 JSON 请求体
app.use(express.json());
// 对于 URL 编码的请求体
app.use(express.urlencoded({ extended: true }));
7 测试接口
接口开发完毕后,就可以进行测试了,这里使用Postman来测试,先测试一下注册接口
然后再测试一下登录接口
可以看到两个接口都已经正常返回数据,这样就可以了
总结
本篇我们讲解了一下用户登录和注册接口的开发,涉及到环境变量的初始化,Orm库的搭建以及路由的配置,熟悉了整套流程,后续的功能开发就可以按照自己的需求完成了。