【Node.js实战】实现登录注册-Express 搭建博客(二)
前言
哈喽,大家好,这里是胖芙,咱这系列的文章主打的就是一个通俗易懂。这个系列的文章会从零开始教你怎么使用 Express.js 去搭建一个能用的博客系统,是真的从零,手把手的那种!!!让你打通 JS 前后端任督二脉!
本系列文章也会收录在公众号《泡芙学前端》中,持续更新中... 欢迎关注
书接上文 【Node.js实战】Express 从零搭建博客系统(一)
上一篇文章中我们已经把项目结构搭建好了,这里就可以直接开始编写功能了。
那么本章节中我们就来实现登录和注册功能,接下来再让我们来看一眼用户模型
用户模型定义
主要包括用户名、密码、昵称、最后的登录时间
// models/User.js
const { DataTypes, Model } = require("sequelize");
const sequelize = require("../config/database");
class User extends Model {}
User.init(
{
username: {
comment: "用户名",
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
password: {
comment: "密码",
type: DataTypes.STRING,
allowNull: false,
},
nickname: {
comment: "昵称",
type: DataTypes.STRING,
allowNull: false,
},
lastOnlineTime: {
comment: "最后登陆时间",
type: DataTypes.DATE,
allowNull: true,
},
},
{
sequelize,
modelName: "User",
}
);
module.exports = User;
定义好了字段之后我们就可以开始写接口了
定义接口
我们现在要实现两个接口:
- localhost:3000/auth/login: 登录
- localhost:3000/auth/register: 注册
// 根目录/app.js
... 具体代码可以看上一章节的实现
// 路由
app.use("/auth", authRoutes);
...
定义路由
// routes/auth.js
const express = require('express');
const router = express.Router();
const authController = require('../controllers/authController');
// 注册控制器
router.post('/register', authController.register);
// 登录控制器
router.post('/login', authController.login);
module.exports = router;
定义控制器
注册
接下来我们先来看注册功能,登录功能的本质其实就是把用户的注册信息存到数据库,但是存入数据库的时候需要对其输入的密码进行加密防止数据库信息泄露时用户信息遭到暴露。具体就下面这么几个步骤:
- 检查用户名是否已存在
- 对密码进行加密处理
- 创建新用户,存入数据库
- 返回信息
这时候我们需要用到 bcrypt 这个依赖,它是用来给密码进行散列加密的,然后在登录的时候我们还会需要它来进行解密
// controllers/authController.js
const User = require("../models/User");
const bcrypt = require("bcrypt");
async function register(req, res) {
const { username, password, nickname } = req.body;
try {
// 检查用户名是否已存在
const existingUser = await User.findOne({ where: { username } });
if (existingUser) {
return res.status(400).json({ msg: "Username already exists" });
}
// 对密码进行加密处理
const hashedPassword = await bcrypt.hash(password, 10);
// 创建新用户
await User.create({ username, password: hashedPassword, nickname });
res.status(201).json({ msg: "User registered successfully" });
} catch (error) {
res.status(500).json({ msg: "Failed to register user" });
}
}
module.exports = { register };
登录
登录的过程其实就是校验用户的账号密码是否能在数据库中匹配出来,同时要对密码进行解密匹配。流程是这样的:
- 看用户是否存在
- 看密码是否匹配
- 更新最后的登录时间
- 创建 token
- 下发用户信息和 token
async function login(req, res) {
const { username, password } = req.body;
try {
// 检查用户名是否存在
const user = await User.findOne({ where: { username } });
if (!user) {
return res.status(401).json({ msg: "Invalid username or password" });
}
// 检查密码是否匹配
const isPasswordMatch = await bcrypt.compare(password, user.password);
if (!isPasswordMatch) {
return res.status(401).json({ msg: "Invalid username or password" });
}
// 更新用户的最后在线时间
user.lastOnlineTime = new Date();
await user.save();
// 创建 token 访问令牌
const token = jwt.sign({ userId: user.id }, "xxx-your-secret-key", {
expiresIn: "24h",
});
// 返回包含令牌、账号名和用户名的响应
res.json({ token, account: user.username, nickname: user.nickname, userId: user.id});
} catch (error) {
res.status(500).json({ msg: "Failed to log in" });
}
}
module.exports = { register, login };
现在我们的两个登录注册接口都编写完成了,接下来就要启动数据库去做接口验证了
启动数据库
耶斯,到这里我们就写完了我们的第一个接口。接下来要做的事情就是把数据库和服务给启动起来。这里我们使用 Docker 来进行 Mysql 的启动。如果你电脑上没安装 Docker,可以去它的官网安装一下,安装好之后在控制台输入 docker -v
有响应说明安装成功了
docker -v
Docker version 20.10.13, build a224086
安装好 Docker 之后,然后我们来安装一下 Mysql 镜像。来输入下面这条命令:
docker run -d -p 3306:3306 -v D:/docker-mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql-container mysql:5.7
然后解释下这条命令的意思
-
拉取5.7版本的 Mysql 镜像
-
将容器内3306端口号映射到宿主机的3306端口
-
将容器内的数据挂载到我Windows电脑上的 D 盘 docker-mysql 目录中
-
初始化设置账号为 root ,密码为123456
-
容器名称设置为 mysql-container
接下来在控制台输入下面这条命令,查看所有容器列表,里面能看到我们的 mysql 容器就说明启动成功了,接下来就可以去连接数据库了
docker ps
后续如果想方便的管理容器,可以下载一个 Docker Desktop 工具,它也是跨平台的,可以去其官网下载
连接数据库
别忘了我们在上一章中还没连接数据库呢,接下来我们去填一下连接数据库的参数,填写完对应的信息后,我们就能把服务给启动起来了
// config/database.js
const { Sequelize } = require("sequelize");
const sequelize = new Sequelize(
// 定义库名
"express-blog",
// 账号
"root",
// 密码
"123456",
{
host: "localhost",
dialect: "mysql",
}
);
module.exports = sequelize;
到了这里之后,我们完成了前置条件:
-
定义数据模型
-
编写接口 localhost:3000/auth/register
-
启动数据库
然后我们现在可以通过 npm run start
把服务给启动起来了,然后发送个注册请求去试试看。
发送请求
这里推荐两个工具:
- Postman:发送请求的软件,我这里用的是这个
- Thunder Client:这个是 VSCode 插件,直接在插件商店里搜索就可以,使用起来也很方便,看个人喜好选择
然后可以看到下面我们成功发送了注册请求
然后我们看下数据库,也看到已经存入了这条数据,说明这接口没问题了~,接下来我们再去验证下登录接口,完成 token 的下发
接下来我们进行登录接口的请求,可以看到其正确的返回了用户的账号名、昵称、token、用户ID,那说明这个接口也通过了,至于异常情况,大家可以自己试一试~~
小结
恭喜你,到这里就更进一步了~ 这一章我们主要完成了登录和注册接口的编写、数据库接入、接口调试的工作,然后下一章中我们会去编写文件上传的接口以及为其加上 token 的鉴权~
如果想要实时收到文章的更新,欢迎关注公众号《泡芙学前端》,同步更新文章中~
转载自:https://juejin.cn/post/7242676549735202874