koa 搭建后端api服务器实战——小白学习记录
前言
首先说明一下,本人并不是专业的程序员,只是工作中需要,想要搭建一个api服务器,取代之前的PHP项目的部分任务,毕竟nodeJS现在很流行,流行就意味着找学习资料容易,相关的库非常丰富,像我这种小白最喜欢了。
很多代码写的肯定不好,欢迎指正。这里将过程分享出来希望对同样的初学者能提供一定的帮助。
这里感谢网上各位大佬免费提供的视频和文字教学,下面是我在网上学习时用到的资料。
文字: koa 搭建后端服务
B站视频:通俗易懂 Node+Koa2从零搭建通用API服务
小目标
请帮我用nodejs实现koa api后台服务器,名为:“koa-server-test”,项目的业务逻辑请按分开,分为:controllers、models、routes、services、utils,入口文件app.js。
数据库使用mariadb,数据库链接为:anpink.uttcare.com:3306/yjdb,账号:root,密码:fp@19921028FP,使用sequelize操作数据库。
数据库中有一个user表保存用户信息,包含“id”、“name”、“passwd”、“isadmin”。实现用户的注册、登录验证功能,使用bcryptjs对密码加密。
1.注册用户信息保存到user表中。当以post访问路由“/user/register”验证name 的唯一性和密码的强度,符合要求时保存数据到数据库user,否则返回错误。
2.当以post访问路由“/user/login”时,查询数据库表,账户密码正确返回登录成功,并使用jsonweb颁发token证书,token有效1个小时。
数据库中有一个test1表保存测试数据,包含“id”、“title1”、“content1”、“other1”。
数据库中有一个test1表保存测试数据,包含“id”、“title2”、“content2”、“other2”。
实现对数据库表“test1”的增、删、改、查功能1.设置token值get请求路径“/api/tset1/query”时,token有效则以json格式返回test1表中所有数据,否则返回对应错误`
2.设置token值get请求路径“/api/tset1/query/:id”时,token有效则以json格式返回test1表中对应id值的数据,否则返回对应错误
3.设置token值,post发送json数据请求路径“/api/tset1/add”时,token有效则在test1表中添加记录,并以json格式所添加的数据,否则返回对应错误
4.设置token值,put发送json数据请求路径“/api/tset1/update/:id”时,token有效则在test1表中修改记录,并以json格式所修改的数据,否则返回对应错误
5.设置token值,delete请求路径“/api/tset1/update/:id”时,token有效则在test1表中删除对应id的记录,并返回删除成功,否则返回对应错误
实现对数据库表"test2"的增、删、改、查功能
1.设置token值get请求路径“/api/tset2/query”时,token有效则以json格式返回test2表中所有数据,否则返回对应错误
2.设置token值get请求路径“/api/tset2/query/:id”时,token有效则以json格式返回test2表中对应id值的数据,否则返回对应错误
3.设置token值,post发送json数据请求路径“/api/tset2/add”时,token有效则在test2表中添加记录,并以json格式所添加的数据,否则返回对应错误
4.设置token值,put发送json数据请求路径“/api/tset2/update/:id”时,token有效则在test2表中修改记录,并以json格式所修改的数据,否则返回对应错误
5.设置token值,delete请求路径“/api/tset2/update/:id”时,token有效则在test2表中删除对应id的记录,并返回删除成功,否则返回对应错误
给出详细的创建步骤,需要的库、并显示需要创建文件的具体代码,代码添加中文注释。保证项目能正常运行。
实现
这是一个比较大的项目,我会分步骤给出具体的实现过程。首先,我们需要创建一个新的 Node.js 项目,并安装必要的库。在你的命令行中运行以下命令来初始化你的项目:
mkdir koa-server-test
cd koa-server-test
npm init -y
安装必要的库:
npm install koa koa-router koa-bodyparser sequelize mysql2 bcryptjs jsonwebtoken
在项目的根目录下创建所需的文件夹和文件:
mkdir controllers models routes services utils
touch app.js
在app.js文件中,我们需要设置路由和服务器:
// app.js
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const userRoutes = require('./routes/user');
const test1Routes = require('./routes/test1');
const test2Routes = require('./routes/test2');
const app = new Koa();
app.use(bodyParser());
app.use(userRoutes.routes());
app.use(test1Routes.routes());
app.use(test2Routes.routes());
app.listen(3000, () => {
console.log('Server is running at http://localhost:3000')
});
module.exports = app;
接下来,我将为你提供controllers, models, routes, services, utils目录下的文件和代码。由于这是一个非常大的项目,我将分多次回复来提供所有的代码。
models
首先,我们需要在models目录下创建index.js、user.js、test1.js和test2.js文件,并在其中定义我们的数据模型。
// models/index.js
const Sequelize = require('sequelize');
const sequelize = new Sequelize('yjdb', 'root', 'fp@19921028FP', {
host: 'anpink.uttcare.com',
port: 3306,
dialect: 'mariadb',
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.user = require('./user.js')(sequelize, Sequelize);
db.test1 = require('./test1.js')(sequelize, Sequelize);
db.test2 = require('./test2.js')(sequelize, Sequelize);
module.exports = db;
// models/user.js
module.exports = (sequelize, Sequelize) => {
const User = sequelize.define('user', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING
},
passwd: {
type: Sequelize.STRING
},
isadmin: {
type: Sequelize.BOOLEAN
}
});
return User;
};
// models/test1.js
module.exports = (sequelize, Sequelize) => {
const Test1 = sequelize.define('test1', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
title1: {
type: Sequelize.STRING
},
content1: {
type: Sequelize.STRING
},
other1: {
type: Sequelize.STRING
}
});
return Test1;
};
// models/test2.js
module.exports = (sequelize, Sequelize) => {
const Test2 = sequelize.define('test2', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
title2: {
type: Sequelize.STRING
},
content2: {
type: Sequelize.STRING
},
other2: {
type: Sequelize.STRING
}
});
return Test2;
};
接下来要创建的是services和utils目录下的文件。
services
在services目录下创建user.js,test1.js和test2.js文件,在这些文件中我们将定义我们的服务逻辑。
// services/user.js
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const db = require('../models/index');
const register = async (name, passwd) => {
// 验证用户名的唯一性和密码的强度
const existingUser = await db.user.findOne({where: {name: name}});
if (existingUser) { throw new Error('Username already exists.'); }
// 对密码进行加密
const hashedPassword = await bcrypt.hash(passwd, 10);
// 保存用户到数据库
const user = await db.user.create({
name: name,
passwd: hashedPassword,
isadmin: false,
});
return user;
};
const login = async (name, passwd) => {
const user = await db.user.findOne({where: {name: name}});
if (!user) { throw new Error('User not found.'); }
const isValid = await bcrypt.compare(passwd, user.passwd);
if (!isValid) { throw new Error('Invalid password.'); }
// 使用jsonweb颁发token证书,token有效1个小时
const token = jwt.sign({ id: user.id }, 'your-secret', { expiresIn: '1h' });
return { user, token };
};
module.exports = {
register,
login,
};
// services/test1.js
const db = require('../models/index');
const getById = async (id) => {
const record = await db.test1.findByPk(id);
if (!record) { throw new Error('Record not found.'); }
return record;
};
const getAll = async () => {
const records = await db.test1.findAll();
return records;
};
const add = async (title1, content1, other1) => {
const record = await db.test1.create({
title1: title1,
content1: content1,
other1: other1,
});
return record;
};
const update = async (id, title1, content1, other1) => {
const record = await db.test1.findByPk(id);
if (!record) { throw new Error('Record not found.'); }
record.title1 = title1;
record.content1 = content1;
record.other1 = other1;
await record.save();
return record;
};
const remove = async (id) => {
const record = await db.test1.findByPk(id);
if (!record) { throw new Error('Record not found.'); }
await record.destroy();
};
module.exports = {
getById,
getAll,
add,
update,
remove,
};
对于test2服务,你可以参考test1的结构,只需要将test1替换为test2即可。
** utils**
在utils目录下,我们需要创建token.js文件,在此文件中我们将处理token的生成和验证。
// utils/token.js
const jwt = require('jsonwebtoken');
const verifyToken = async (ctx, next) => {
const authHeader = ctx.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return ctx.throw(401, 'No token found.');
try {
const decoded = jwt.verify(token, 'your-secret');
ctx.state.user = decoded;
} catch(err) {
return ctx.throw(401, 'Invalid token.');
}
await next();
};
module.exports = {
verifyToken,
};
接下来我们会在controllers和routes目录下创建相应的文件。
** controllers**
在controllers目录下,我们需要创建user.js,test1.js和test2.js文件,在这些文件中我们将定义我们的控制器逻辑。
// controllers/user.js
const userService = require('../services/user');
const register = async (ctx) => {
const { name, passwd } = ctx.request.body;
try {
const user = await userService.register(name, passwd);
ctx.body = user;
} catch (error) {
ctx.throw(400, error.message);
}
};
const login = async (ctx) => {
const { name, passwd } = ctx.request.body;
try {
const { user, token } = await userService.login(name, passwd);
ctx.body = { user, token };
} catch (error) {
ctx.throw(400, error.message);
}
};
module.exports = {
register,
login,
};
// controllers/test1.js
const test1Service = require('../services/test1');
const getById = async (ctx) => {
const { id } = ctx.params;
try {
const record = await test1Service.getById(id);
ctx.body = record;
} catch (error) {
ctx.throw(400, error.message);
}
};
const getAll = async (ctx) => {
try {
const records = await test1Service.getAll();
ctx.body = records;
} catch (error) {
ctx.throw(400, error.message);
}
};
const add = async (ctx) => {
const { title1, content1, other1 } = ctx.request.body;
try {
const record = await test1Service.add(title1, content1, other1);
ctx.body = record;
} catch (error) {
ctx.throw(400, error.message);
}
};
const update = async (ctx) => {
const { id } = ctx.params;
const { title1, content1, other1 } = ctx.request.body;
try {
const record = await test1Service.update(id, title1, content1, other1);
ctx.body = record;
} catch (error) {
ctx.throw(400, error.message);
}
};
const remove = async (ctx) => {
const { id } = ctx.params;
try {
await test1Service.remove(id);
ctx.body = 'Record deleted successfully.';
} catch (error) {
ctx.throw(400, error.message);
}
};
module.exports = {
getById,
getAll,
add,
update,
remove,
};
对于test2控制器,你可以参考test1的结构,只需要将test1替换为test2即可。
routes
在routes目录下,我们也需要创建相同的文件,并在其中定义我们的路由。
// routes/user.js
const Router = require('koa-router');
const userController = require('../controllers/user');
const { verifyToken } = require('../utils/token');
const router = new Router();
router.post('/user/register', userController.register);
router.post('/user/login', userController.login);
module.exports = router;
// routes/test1.js
const Router = require('koa-router');
const test1Controller = require('../controllers/test1');
const { verifyToken } = require('../utils/token');
const router = new Router();
router.get('/api/test1/query', verifyToken, test1Controller.getAll);
router.get('/api/test1/query/:id', verifyToken, test1Controller.getById);
router.post('/api/test1/add', verifyToken, test1Controller.add);
router.put('/api/test1/update/:id', verifyToken, test1Controller.update);
router.delete('/api/test1/delete/:id', verifyToken, test1Controller.remove);
module.exports = router;
对于test2路由,你可以参考test1的结构,只需要将test1替换为test2即可。
至此,我们已经完成了所有的代码编写。你可以通过运行node app.js启动你的服务器。如果你在使用过程中遇到任何问题,都可以随时向我提问。
用postman的测试连接和测试方法
当你的服务器运行后,你可以使用Postman来测试你的 API。
-
启动 Postman。
-
在请求选项中选择 “POST”,然后在 URL 栏中输入
http://localhost:3000/user/register。点击 “Body” 选项卡,然后选择 “raw” 和 “JSON”。在文本框中输入相应的 JSON 数据,例如:
{
"name": "yourusername",
"passwd": "yourpassword"
}
-
点击 “Send” 按钮,你应该会在响应区域看到新注册用户的信息。
-
类似的,你可以使用相同的方法来测试其他的 API。例如,你可以使用以下的 URL 和 JSON 数据来测试登录功能:
URL:http://localhost:3000/user/login
{
"name": "yourusername",
"passwd": "yourpassword"
}
-
对于需要验证 token 的 API,你需要先进行登录操作,然后将登录后返回的 token 添加到请求的 “Authorization” 头中。你可以通过点击 “Headers” 选项卡,然后在 “Key” 栏中输入 “Authorization”,在 “Value” 栏中输入 “Bearer yourtoken” 来完成这个操作。
-
对于需要发送 JSON 数据的 API,你可以按照第 2 步的操作来发送相应的数据。
-
对于需要指定路径参数的 API,你可以在 URL 中指定相应的参数。例如,你可以使用
http://localhost:3000/api/test1/query/1来查询 ID 为 1 的记录。 -
对于需要发送 PUT 或 DELETE 请求的 API,你只需要将请求选项中的 “POST” 改为 “PUT” 或 “DELETE” 即可。
这就是使用 Postman 测试你的 API 的基本方法,如果你在使用过程中遇到任何问题,都可以向我提问。
详细的每个API的测试方法:
-
用户注册
- HTTP Method: POST
- URL:
http://localhost:3000/user/register - Body (raw, JSON):
{ "name": "testuser", "passwd": "testpassword" }点击"Send",如果成功,你将在响应中看到新创建的用户信息。
-
用户登录
- HTTP Method: POST
- URL:
http://localhost:3000/user/login - Body (raw, JSON):
{ "name": "testuser", "passwd": "testpassword" }点击"Send",如果成功,你将在响应中看到用户信息和一个新的JWT令牌。记住这个令牌,因为在接下来的请求中,你需要将其添加到"Authorization"头中。
-
获取所有test1记录
- HTTP Method: GET
- URL:
http://localhost:3000/api/test1/query - Headers: Key - Authorization, Value - Bearer [your JWT token]
点击"Send",如果成功,你将在响应中看到所有test1的记录。
-
获取单个test1记录
- HTTP Method: GET
- URL:
http://localhost:3000/api/test1/query/1(假设你想获取ID为1的记录) - Headers: Key - Authorization, Value - Bearer [your JWT token]
点击"Send",如果成功,你将在响应中看到ID为1的test1记录。
-
添加一个新的test1记录
- HTTP Method: POST
- URL:
http://localhost:3000/api/test1/add - Headers: Key - Authorization, Value - Bearer [your JWT token]
- Body (raw, JSON):
{ "title1": "New Title", "content1": "New Content", "other1": "Other Info" }点击"Send",如果成功,你将在响应中看到新创建的test1记录。
-
更新一个test1记录
- HTTP Method: PUT
- URL:
http://localhost:3000/api/test1/update/1(假设你想更新ID为1的记录) - Headers: Key - Authorization, Value - Bearer [your JWT token]
- Body (raw, JSON):
{ "title1": "Updated Title", "content1": "Updated Content", "other1": "Updated Other Info" }点击"Send",如果成功,你将在响应中看到更新后的test1记录。
-
删除一个test1记录
- HTTP Method: DELETE
- URL:
http://localhost:3000/api/test1/delete/1(假设你想删除ID为1的记录) - Headers: Key - Authorization, Value - Bearer [your JWT token]
点击"Send",如果成功,你将在响应中看到删除信息。
对于test2的操作,方法完全相同,只需将上述URL中的test1替换为test2即可。
改进一下:在register组件中增加验证用户密码强度的验证
在注册组件中增加密码强度的验证是一个很好的实践,这将提高系统的安全性。下面是一个简单的例子,用于检查密码是否包含数字、小写字母、大写字母和特殊字符,并且长度至少为8个字符。
首先,我们在controllers/user.js的register函数中添加密码强度的验证:
// controllers/user.js
const userService = require('../services/user');
const isStrongPassword = (password) => {
// 密码至少包含一个数字,一个大写字母,一个小写字母,一个特殊字符,并且长度至少为8个字符
const regex = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,}$/;
return regex.test(password);
}
const register = async (ctx) => {
const { name, passwd } = ctx.request.body;
// 验证密码强度
if (!isStrongPassword(passwd)) {
ctx.throw(400, 'Password is not strong enough. It should contain at least one number, one uppercase letter, one lowercase letter, one special character, and be at least 8 characters long.');
}
try {
const user = await userService.register(name, passwd);
ctx.body = user;
} catch (error) {
ctx.throw(400, error.message);
}
};
// 其他代码...
这个正则表达式 ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,}$ 的含义是:
(?=.*[0-9]):密码必须包含至少一个数字。(?=.*[a-z]):密码必须包含至少一个小写字母。(?=.*[A-Z]):密码必须包含至少一个大写字母。(?=.*[!@#$%^&*]):密码必须包含至少一个特殊字符(包括!@#$%^&*)。.{8,}:密码长度必须至少为8个字符。
注意,这只是一个基本的密码强度检查,你可以根据你的业务需求调整这个正则表达式。
在上面的项目中增加对用户的管理,对应增、删、改、查功能,当用户登录后查看登录用户名对应的“isadmin”值是否 大于0,如果大于0可以实现增、删、改、查功能权限,否则返回不具备权限
这里需求需要在服务层增加新的函数来实现用户的增删改查,并在控制器层添加相应的函数来处理请求。然后在路由层添加新的路由。在每个需要权限的请求中,我们都需要检查用户的isadmin字段。
首先,我们在services/user.js中添加新的函数:
// services/user.js
// 其他代码...
const getAllUsers = async () => {
const users = await db.user.findAll();
return users;
};
const getUserById = async (id) => {
const user = await db.user.findByPk(id);
if (!user) { throw new Error('User not found.'); }
return user;
};
const updateUser = async (id, name, passwd, isadmin) => {
const user = await db.user.findByPk(id);
if (!user) { throw new Error('User not found.'); }
user.name = name;
user.passwd = passwd;
user.isadmin = isadmin;
await user.save();
return user;
};
const removeUser = async (id) => {
const user = await db.user.findByPk(id);
if (!user) { throw new Error('User not found.'); }
await user.destroy();
};
module.exports = {
register,
login,
getAllUsers,
getUserById,
updateUser,
removeUser,
};
然后,我们在controllers/user.js中添加新的函数:
// controllers/user.js
// 其他代码...
const getAllUsers = async (ctx) => {
if (!ctx.state.user.isadmin) {
return ctx.throw(403, 'Permission denied.');
}
try {
const users = await userService.getAllUsers();
ctx.body = users;
} catch (error) {
ctx.throw(400, error.message);
}
};
const getUserById = async (ctx) => {
if (!ctx.state.user.isadmin) {
return ctx.throw(403, 'Permission denied.');
}
const { id } = ctx.params;
try {
const user = await userService.getUserById(id);
ctx.body = user;
} catch (error) {
ctx.throw(400, error.message);
}
};
const updateUser = async (ctx) => {
if (!ctx.state.user.isadmin) {
return ctx.throw(403, 'Permission denied.');
}
const { id } = ctx.params;
const { name, passwd, isadmin } = ctx.request.body;
try {
const user = await userService.updateUser(id, name, passwd, isadmin);
ctx.body = user;
} catch (error) {
ctx.throw(400, error.message);
}
};
const removeUser = async (ctx) => {
if (!ctx.state.user.isadmin) {
return ctx.throw(403, 'Permission denied.');
}
const { id } = ctx.params;
try {
await userService.removeUser(id);
ctx.body = 'User deleted successfully.';
} catch (error) {
ctx.throw(400, error.message);
}
};
module.exports = {
register,
login,
getAllUsers,
getUserById,
updateUser,
removeUser,
};
最后,我们在routes/user.js中添加新的路由:
// routes/user.js
// 其他代码...
router.get('/user/query', verifyToken, userController.getAllUsers);
router.get('/user/query/:id', verifyToken, userController.getUserById);
router.put('/user/update/:id', verifyToken, userController.updateUser);
router.delete('/user/delete/:id', verifyToken, userController.removeUser);
module.exports = router;
现在,只有isadmin字段大于0的用户才能访问这些新的API。如果用户尝试访问这些API但没有相应的权限,服务器将返回403错误。
在上面的项目在增加 logout功能
说明
在很多应用中,登出功能通常涉及的是在客户端删除存储的token,因为token是在客户端存储并在每次请求时发送给服务器的。
思路
然而,如果你想在服务器端实现登出功能,你可以创建一个记录所有已登出token的黑名单,然后在接收到请求时检查token是否在这个列表中。如果token在黑名单中,那么请求就被认为是无效的,即使token本身是有效的。
以下是如何在你的应用中实现这个功能:
首先,我们在utils/token.js中增加一个黑名单:
// utils/token.js
// 其他代码...
let blackList = [];
const addToBlackList = (token) => {
blackList.push(token);
};
const isTokenInBlackList = (token) => {
return blackList.includes(token);
};
module.exports = {
verifyToken,
addToBlackList,
isTokenInBlackList,
};
接着,我们在services/user.js中增加一个登出函数:
// services/user.js
// 其他代码...
const logout = async (token) => {
tokenUtil.addToBlackList(token);
};
module.exports = {
// 其他函数...
logout,
};
然后,在controllers/user.js中增加一个logout函数:
// controllers/user.js
// 其他代码...
const logout = async (ctx) => {
const token = ctx.headers['authorization'].split(' ')[1];
await userService.logout(token);
ctx.body = 'Logged out successfully.';
};
module.exports = {
// 其他函数...
logout,
};
最后,在routes/user.js中添加一个新的路由:
// routes/user.js
// 其他代码...
router.post('/user/logout', verifyToken, userController.logout);
module.exports = router;
现在,当你调用登出API时,你的token就会被添加到黑名单中,所有包含这个token的进一步请求都会被视为无效。
对应接口在postman中的详细测试连接和方法实现
以下是在Postman中测试这些新功能的步骤:
-
获取所有用户
- HTTP Method: GET
- URL:
http://localhost:3000/user/query - Headers: Key - Authorization, Value - Bearer [your JWT token]
点击"Send",如果成功,你将在响应中看到所有用户的列表。
-
获取单个用户
- HTTP Method: GET
- URL:
http://localhost:3000/user/query/1(假设你想获取ID为1的用户) - Headers: Key - Authorization, Value - Bearer [your JWT token]
点击"Send",如果成功,你将在响应中看到ID为1的用户信息。
-
更新一个用户
- HTTP Method: PUT
- URL:
http://localhost:3000/user/update/1(假设你想更新ID为1的用户) - Headers: Key - Authorization, Value - Bearer [your JWT token]
- Body (raw, JSON):
{ "name": "Updated Name", "passwd": "UpdatedPassword123!", "isadmin": 1 }点击"Send",如果成功,你将在响应中看到更新后的用户信息。
-
删除一个用户
- HTTP Method: DELETE
- URL:
http://localhost:3000/user/delete/1(假设你想删除ID为1的用户) - Headers: Key - Authorization, Value - Bearer [your JWT token]
点击"Send",如果成功,你将在响应中看到删除信息。
-
登出
- HTTP Method: POST
- URL:
http://localhost:3000/user/logout - Headers: Key - Authorization, Value - Bearer [your JWT token]
点击"Send",如果成功,你将在响应中看到登出成功的信息。
请注意,对于需要管理员权限的API,你需要使用一个isadmin字段大于0的用户的token,否则服务器将返回403错误。
————————————————————————————
————————————————————————————
实现在上面的项目中增加作为用户管理员,作为添加用户的功能
为了添加一个新用户的管理功能,我们需要在服务层和控制器层添加新的函数,并在路由层添加新的路由。这个功能应该只有管理员用户才能访问。
首先,我们在services/user.js中添加一个addUser函数:
// services/user.js
// 其他代码...
const addUser = async (name, passwd, isadmin) => {
const user = await db.user.create({ name, passwd, isadmin });
return user;
};
module.exports = {
// 其他函数...
addUser,
};
然后,在controllers/user.js中添加一个addUser函数:
// controllers/user.js
// 其他代码...
const addUser = async (ctx) => {
if (!ctx.state.user.isadmin) {
return ctx.throw(403, 'Permission denied.');
}
const { name, passwd, isadmin } = ctx.request.body;
try {
const user = await userService.addUser(name, passwd, isadmin);
ctx.body = user;
} catch (error) {
ctx.throw(400, error.message);
}
};
module.exports = {
// 其他函数...
addUser,
};
最后,在routes/user.js中添加一个新的路由:
// routes/user.js
// 其他代码...
router.post('/user/add', verifyToken, userController.addUser);
module.exports = router;
现在,只有isadmin字段大于0的用户才能访问这个API。如果用户尝试访问这个API但没有相应的权限,服务器将返回403错误。
在Postman中测试这个功能的方法如下:
- HTTP Method: POST
- URL:
http://localhost:3000/user/add - Headers: Key - Authorization, Value - Bearer [your JWT token]
- Body (raw, JSON):
{
"name": "newuser",
"passwd": "NewUser123!",
"isadmin": 0
}
点击"Send",如果成功,你将在响应中看到新添加的用户信息。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)