node 服务器进行模块化构建
新建一个命名为 api 的文件夹作为服务器
根目录安装依赖npm install
package.json 配置
下面是各个模块的功能
// 连接数据库
var mongoose = require('mongoose');
const IP = '127.0.0.1'//服务器公网ip
const PORT = '27017';//端口
const DB_NAME = 'web';//数据库名
const USERNAME = 'web';//用户名
const PASSWORD = '123456';//密码
const db = mongoose.connection;
mongoose.connect(`mongodb://${USERNAME}:${PASSWORD}@${IP}:${PORT}/${DB_NAME}?authSource=admin`,{useNewUrlParser:true,useUnifiedTopology:true})
//2.连接成功
mongoose.connection.on('connected',function(){
console.log('连接成功:');
// db.dropDatabase();//删除当前数据库
})
//3.连接失败
mongoose.connection.on('error',function(err){
console.log('连接错误:',err);
})
//4.断开连接
mongoose.connection.on('disconnection',function(){
console.log('断开连接');
})
module.exports = mongoose;
var mongoose = require('mongoose');
var userSchema = require('../schemas/userSchema');
//创建 user 模型 ( 需要使用 users 表结构 )
module.exports = mongoose.model('User', userSchema, 'users' );
var express = require('express');
var jwt = require('jsonwebtoken');
var secretKey = 'nodejs'
//创建express子路由
var router = express.Router();
//导入User模型对象, 用来处理用户的登陆
var userModel = require("../models/userModel")
//api接口,处理注册用户的请求
router.post('/register', (req, res) => {
//req 请求对象
console.log('req.body', req.body);
var { username, password } = req.body;
//查询用户是否存在
userModel.find({ username }).then((data)=>{
if (data.length != 0) { //用户存在
res.send({ code: 403, msg: "用户已存在,注册失败!" });
} else { //用户不存在, 插入新用户到数据表中
userModel.insertMany({username,password}).then((data)=>{
if (data.length != 0) { //如果没有出错
res.send({ code: 200, msg: "注册成功!" });
}
}).catch((err)=>{
res.send({ code: 400, msg: "注册失败!" });
})
}
}).catch(()=>{
})
})
router.post('/login', async (req, res) => {
const { username,password } = req.body;
try {
// 查询数据库获取用户信息
const data = await userModel.findOne({ username });
if (!data || data.username !== username||data.password !== password) {
return res.send({
code: 401,
msg: '用户不存在或密码错误!'
});
}
// 生成JWT令牌并返回给客户端
const token = jwt.sign({ id: data._id }, secretKey, { expiresIn: '2h' });
res.cookie('jwtToken', token, { httpOnly: true }).send({
code: 200,
msg: "登陆成功!",
token:'Bearer '+ token
});
} catch (error) {
console.log(error);
res.status(500).send('Internal server error');
}
});
module.exports = router;
var mongoose = require('mongoose');
//创建 user 表结构 并抛出
module.exports = mongoose.Schema({
username: String,
password: String
},{ timestamps: false,versionKey: false}); // 关闭自动生成 createdAt 和 updatedAt 字段
/**
* 注释:身份验证中间件
*
* @param {Object} req 请求对象
* @param {Object} res 响应对象
* @param {Function} next 下一步回调函数
*/
function authMiddle(req, res, next) {
if (!req) {
res.send({
success: false,
msg: "token错误"
})
}
try {
next()
} catch (error) {
res.send({
success: false,
msg: error
})
}
}
module.exports={
authMiddle
}
//1.引入express模块
var express = require('express');
const bodyParser = require('body-parser')
const cors = require('cors');
var expressjwt = require('express-jwt').expressjwt
//连接mongodb数据库
require("./db/index.js")
//2.创建express实例对象
var app = express();
app.use(cors()) //跨域处理
app.use(bodyParser.json()) //解析请求体
//处理post参数
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//设置中间件 验证token的有效性
app.use(expressjwt({
secret: 'nodejs',
algorithms: ['HS256']
}).unless({
path: [ //接口白名单, 这里的接口时免除token验证的
'/api/user/login',
'/api/user/register'
]
}))
var userRouter = require('./router/user')
var funcRouter = require('./router/func')
//应用 用户的 子路由
app.use( "/api/user", userRouter )
//应用用户的功能菜单列表
app.use( "/api/func", funcRouter )
//3.监听端口
app.listen(8090, () => {
console.log('服务器运行在 http://localhost:8090');
});
至此,我们就搭建好了一个本地服务器,可以实现登录和注册
接下来简单写个页面 ajax.html 请求验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.display{
display: block;
width: 100%;
margin-bottom: 10px;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script>
</head>
<body>
<div class="display">
<span>注册账号:</span>
<input id="username" type="text" placeholder="用户名">
<input id="password" type="text" placeholder="密码">
<button onclick="register()">注册</button>
</div>
<div class="display">
<span>登录账号:</span>
<input id="usernameLogin" type="text" placeholder="用户名">
<input id="passwordLogin" type="text" placeholder="密码">
<button onclick="login()">登录</button>
</div>
<div class="display">
<span>新增功能菜单:</span>
<input id="name" type="text" placeholder="功能名称">
<input id="url" type="text" placeholder="功能地址">
<input id="desc" type="text" placeholder="功能描述">
<button onclick="addMenu()">新增</button>
</div>
<div class="display">
<span>删除功能菜单:</span>
<input id="funcId" type="text" placeholder="功能id">
<button onclick="delMenu()">删除</button>
</div>
<div class="display">
<span>修改功能菜单:</span>
<input id="funcName" type="text" placeholder="功能原名称">
<input id="updateFuncName" type="text" placeholder="功能修改名称">
<button onclick="changeMenuName()">修改功能名称</button>
</div>
</body>
<script>
function changeMenuName() {
const inputFuncName = document.getElementById('funcName').value;
const inputUpdateFuncName = document.getElementById('updateFuncName').value;
$.ajax({
url: "http://127.0.0.1:8090/api/func/changeFunc", // 设置请求地址
type: "post", // 或者"POST"等其他HTTP请求类型
headers: { //请求头
Authorization: localStorage.getItem('token') //这是获取的token
},
dataType: "json", // 指定返回结果的格式为JSON
data: {
name:inputFuncName,
updateName:inputUpdateFuncName
}, // 传递参数,这里的key-value对应于后台接收参数时的名称与值
success: function(response) {
console.log(response);
},
error: function() {
console.log("失败");
}
});
}
function delMenu() {
const inputFuncId = document.getElementById('funcId').value;
$.ajax({
url: "http://127.0.0.1:8090/api/func/delFunc", // 设置请求地址
type: "delete", // 或者"POST"等其他HTTP请求类型
headers: { //请求头
Authorization: localStorage.getItem('token'), //这是获取的token
},
dataType: "json", // 指定返回结果的格式为JSON
data: {
_id:inputFuncId
}, // 传递参数,这里的key-value对应于后台接收参数时的名称与值
success: function(response) {
console.log(response);
},
error: function() {
console.log("失败");
}
});
}
function addMenu(){
const inputName = document.getElementById('name').value;
const inputUrl = document.getElementById('url').value;
const inputDesc = document.getElementById('desc').value;
$.ajax({
url: "http://127.0.0.1:8090/api/func/addFunc", // 设置请求地址
type: "post", // 或者"POST"等其他HTTP请求类型
headers: { //请求头
Authorization: localStorage.getItem('token'), //这是获取的token
},
dataType: "json", // 指定返回结果的格式为JSON
data: {
name: inputName,
url: inputUrl,
desc:inputDesc
}, // 传递参数,这里的key-value对应于后台接收参数时的名称与值
success: function(response) {
console.log("成功");
console.log(response); // 处理服务器返回的数据
getMenu()
},
error: function() {
console.log("失败");
}
});
}
function getMenu(tokens) {
$.ajax({
url: "http://127.0.0.1:8090/api/func/funcMenu", // 设置请求地址
type: "get", // 或者"POST"等其他HTTP请求类型
headers: { //请求头
Authorization: localStorage.getItem('token'), //这是获取的token
},
dataType: "json", // 指定返回结果的格式为JSON
data: {}, // 传递参数,这里的key-value对应于后台接收参数时的名称与值
success: function(response) {
console.log("成功");
console.log(response); // 处理服务器返回的数据
},
error: function() {
console.log("失败");
}
});
}
function register() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
$.ajax({
url: "http://127.0.0.1:8090/api/user/register", // 设置请求地址
type: "post", // 或者"POST"等其他HTTP请求类型
dataType: "json", // 指定返回结果的格式为JSON
data: {
username: username,
password: password
}, // 传递参数,这里的key-value对应于后台接收参数时的名称与值
success: function(response) {
console.log(response); // 处理服务器返回的数据
},
error: function() {
console.log("失败");
}
});
}
function login() {
const usernameLogin = document.getElementById('usernameLogin').value;
const passwordLogin = document.getElementById('passwordLogin').value;
$.ajax({
url: "http://127.0.0.1:8090/api/user/login", // 设置请求地址
type: "post", // 或者"POST"等其他HTTP请求类型
dataType: "json", // 指定返回结果的格式为JSON
data: {
username: usernameLogin,
password: passwordLogin
}, // 传递参数,这里的key-value对应于后台接收参数时的名称与值
success: function(response) {
console.log("成功");
console.log(response); // 处理服务器返回的数据
localStorage.setItem('token', response.token)
},
error: function() {
console.log("失败");
}
});
}
</script>
</html>
注册功能
登录功能
接下来是增删改查的功能接口
var mongoose = require('mongoose');
var userSchema = require('../schemas/funcSchema');
//创建 user 模型 ( 需要使用 user 表结构 )
module.exports = mongoose.model('Func', userSchema, 'func' );
var mongoose = require('mongoose');
//创建 func 表结构 并抛出
module.exports = mongoose.Schema({
name: String,
url: String,
desc: String
},{ timestamps: false,versionKey: false })
var express = require('express');
var commonFunc = require('../auth')
//创建express子路由
var router = express.Router();
//导入function模型对象, 用来处理用户的登陆
var funcModel = require("../models/funcModel")
// 自定义中间件 - 校验JWT令牌
// 权限判断的中间件
//添加功能菜单
router.post('/addFunc',commonFunc.authMiddle,(req, res) => {
//req 请求对象
console.log('req.body', req.body);
var { name, url,desc } = req.body;
//查询用户是否存在
funcModel.find({ name }).then((data)=>{
if (data.length != 0) { //功能存在
res.send({ code: 403, msg: "功能菜单已存在,添加失败!" });
} else { //用户不存在, 插入新用户到数据表中
funcModel.insertMany({name,url,desc}).then((data)=>{
if (data.length != 0) { //如果没有出错
res.send({ code: 200, msg: "添加成功!" });
}
}).catch((err)=>{
res.send({ code: 400, msg: err });
})
}
})
})
//删除功能菜单
router.delete('/delFunc',commonFunc.authMiddle,(req, res) => {
//req 请求对象
var { _id } = req.body;
//查询用户是否存在
funcModel.find({ _id }).then((data)=>{
console.log('data',data)
if (data.length != 0) { //功能存在
funcModel.deleteOne({ _id: _id })
.then(() => {
res.send({
code: 200,
msg: "删除成功!",
});
})
.catch(err => {
res.send(err)
});
}else{
res.send({ code: 400, msg: "功能不存在,删除失败!" });
}
}).catch((err)=>{
res.send(err)
})
})
//改变功能菜单名称
router.post('/changeFunc',commonFunc.authMiddle,(req, res) => {
var { name,updateName } = req.body;
funcModel.find({ name }).then((data)=>{
if (data.length != 0) { //功能存在
funcModel.updateOne({ name: name }, { name: updateName })
.then(() => {
res.send({
code: 200,
msg: "修改成功!",
});
})
.catch(err => {
res.send(err)
});
}else{
res.send({ code: 400, msg: "功能不存在,修改失败!" });
}
}).catch((err)=>{
res.send(err)
})
})
//获取功能菜单列表数据
router.get('/funcMenu',commonFunc.authMiddle,(req, res) => {
//查询用户是否存在
funcModel.find().then((data)=>{
res.send({
code: 200,
msg: "获取成功!",
data
});
}).catch((err)=>{
res.send(err)
})
})
module.exports = router;
其中需要注意的是中间件函数的应用commonFunc,判断登录状态 token 是否失效!
至此,简单的注册、登录、增删改查的接口开发完成。