基于Express+Ejs实现带登录认证的多模块增删改查后台管理系统

上篇文章只是简单的在后端用访问路由然后render渲染ejs文件去展示后端存放的数据,现在想添加一些增删改查的功能,以及路由的本质就是所谓对数据的增删改查,不同的路由对应这不同的一组数据,也就是数据库中的数据表单。为了区分不同的路由,我们用Router引入的方式,把操作不同数据表的路由写在不同的文件,然后最后作为中间件绑定这些路由。而且我们在写好展示数据增删改查的列表之后我们不希望用户可以随意访问,也就是需要登录,那么不希望每次都需要登录我们就需要去设置cookie。这样不会因为刷新而重新登录。

1.使用路由模块化管理项目。

​编辑

展示学生列表的路由我们放在了student.js路由文件中。其他的只是展示一个res.send('user路由')仅此而已。

javascript 复制代码
const express = require('express')
const app = express()
const fs = require('fs/promises')
const path = require('node:path')
const userRouter = require('./routes/user')
const goodsRouter = require('./routes/goods')
const studentRouter = require('./routes/students')
const cookieParser = require('cookie-parser')
app.set('view engine','ejs')
app.set('views',path.resolve(__dirname,'views'))
app.use(express.static(path.resolve(__dirname,'public')))
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser())
//只要路由在中间件下面都生效
//路由生效
app.use("/user",userRouter)
app.use("/goods",goodsRouter)
app.use("/students",studentRouter)
//Router路由 express中创建的对象
const router = express.Router()
//router实际上是一个中间件 可以在该中间件上绑定各种路由 以及其他的中间件
router.get('/hello',(req,res)=>{
    res.send('/je;;o')
})
// app.get('/get-cookie',(req,res)=>{
//     //给客户端发送一个cookie
//     res.cookie("username","admin")
//     res.send('cookie已经发送')
// })
// app.get('/hello',(req,res)=>{
//     /*
//         安装中间件 使用express解析cookie
//             1.安装cookie-parser
//             2.引入
//                 const cookieParser = require('cookie-parser')
//             3.中间件使用
//                 app.use(cookieParser())
//     */
//     console.log(req.cookies)
//     res.send('hello')
// })
app.get('/',(req,res)=>{
    console.log(req.cookies)
    res.render('login')
})
/*
    cookie
        cookie是http协议用来解决无状态问题的技术
        cookie本质就是一个头
            -服务器以响应头的形式将cookie发送给客户端
                客户端收到以后将其存储并在下次向服务器发送请求时将其传回
            maxAge设置cookie有效时间 单位是毫秒
*/
app.post('/login',(req,res)=>{
    const {username,password} = req.body
    if(username === 'admin'&& password==='123123'){
       // res.send('登录成功')
       //将用户名放入cookie
       //cookie是有有效期的 默认情况下 cookie是一次会话(session) 会话就是打开关闭浏览器的过程
       res.cookie('username',username,{
            //expires:new Date(2025,8,4)
            maxAge:1000*60*60*24*30
       })
       res.redirect('/students/list')
    }else{
        res.send('登录失败')
    }
})
app.get('/delete-cookie',(req,res)=>{
    //cookie一旦发送给浏览器就不能修改了
    //但是可以通过新的cookie替换旧cookie
    res.cookie("username","qdsadqw",{
        maxAge:0
    })
    res.send('删除 cookie')
})
app.use(router)
console.log(router)
app.use((req,res)=>{
    res.status(404)
    res.send('你访问的服务器被劫持了')
})
app.listen(3000,()=>{
    console.log('服务器已经启动')
})

首先我们直接引入不同的Router文件,然后用中间件去绑定,第一个参数'students'代表我们在访问路由需要加前缀students ,防止比如路由文件里面有相同的路由命名。

然后一般登录的话 /路径的路由我们直接用app去定义,其他的不同路径我们分别根据操作不同的数据去设置对应的路由文件。

2.学生路由中的增删改查

我们通过访问路由去对列表进行增删改查,实际上就是在操作数据库中表中的数据,仅此而已,但我们现在并没有绑定数据库,所以我们直接操作我们定义的数组就可以了,但是我们的数组作为变量刷新的话会丢失,我们需要存储在磁盘中。我们创建一个json文件去保存,然后每次展示列表的时候都去读取json文件中的数据然后转化成对象的形式。

​编辑

javascript 复制代码
const express = require('express')
const router = express.Router()
let STUDENT = require('../data/students.json')
const fs = require('fs/promises')
const path = require('path')
//学生列表路由
router.get('/list',(req,res)=>{
    if(req.cookies.username){
         res.render('students',{stu:STUDENT})
    }else{
        res.redirect('/')
    }
    
})
//添加学生路由
router.post('/add',(req,res,next)=>{
    const id = STUDENT.at(-1)?STUDENT.at(-1).id+1:1
    const newUser ={
        id:id,
        name:req.body.name,
        age:+req.body.age,
        gender:req.body.gender,
        address:req.body.address
    }
    STUDENT.push(newUser)
    //将新的数据写入json文件
    // fs.writeFile(path.resolve(__dirname,'../data/students.json'),JSON.stringify(STUDENT))
    // .then(r=>{
    //     res.redirect('/students/list')
    // })
    // .catch(r=>{
    //     console.log('添加失败')
    //     res.send('添加失败')
    // })
    //调用next交由后续路由处理
    next()
})
router.get('/delete',(req,res,next)=>{
    const id = +req.query.id
    //根据id删除学生
    STUDENT=STUDENT.filter(stu=>stu.id!==id)
//     fs.writeFile(path.resolve(__dirname,'./data/students.json'),
//     JSON.stringify(STUDENT)
// )
//     res.redirect('/students')
    next()
})
router.post('/update-user',(req,res,next)=>{
    const id =  +req.body.id
    const {name,age,gender,address} = req.body
    //修改学生信息
    //根据学生id获取学生对象
    const user = STUDENT.find(item=>item.id===id)
    user.name=name
    user.age=age
    user.gender=gender
    user.address=address
//     fs.writeFile(path.resolve(__dirname,'./data/students.json'),
//     JSON.stringify(STUDENT)
// )
//     res.redirect('/students')
    next()
})
router.get('/update',(req,res)=>{
    const id = +req.query.id
    const student = STUDENT.find(item=>item.id===id)
    res.render('update',{student})
})
//处理存储文件的中间件
router.use((req,res)=>{
      fs.writeFile(path.resolve(__dirname,'../data/students.json'),JSON.stringify(STUDENT))
    .then(r=>{
        res.redirect('/students/list')
    })
    .catch(r=>{
        console.log('添加失败')
       // res.send('添加失败')
    })
})
module.exports = router

增删改查无非就是通过传过来的post中表单的id参数然后进行更改,只不过更新的话需要传过来id然后筛选出那个对象,然后将对象的数据生成一个新的表单,然后对这个表单进行操作然后把生成的新对象push进数组即可。

最后不管增删改查那一步都执行中间件router.use()用fs模块的方法writeFile把json文件重新书写,把最新生成的数组对象写进去然后重新读取。

其实计算机编程就是在操作数据,对数据进行增删改查,就是这样。

3.Cookie的使用

安装中间件 使用express解析cookie

1.安装cookie-parser

2.引入

const cookieParser = require('cookie-parser')

3.中间件使用

app.use(cookieParser())

javascript 复制代码
const cookieParser = require('cookie-parser')
app.use(cookieParser())
app.post('/login',(req,res)=>{
    const {username,password} = req.body
    if(username === 'admin'&& password==='123123'){
       // res.send('登录成功')
       //将用户名放入cookie
       //cookie是有有效期的 默认情况下 cookie是一次会话(session) 会话就是打开关闭浏览器的过程
       res.cookie('username',username,{
            //expires:new Date(2025,8,4)
            maxAge:1000*60*60*24*30
       })
       res.redirect('/students/list')
    }else{
        res.send('登录失败')
    }
})
app.get('/delete-cookie',(req,res)=>{
    //cookie一旦发送给浏览器就不能修改了
    //但是可以通过新的cookie替换旧cookie
    res.cookie("username","qdsadqw",{
        maxAge:0
    })
    res.send('删除 cookie')
})

这样我们就可以设置cooke在响应头中,浏览器会自动存储进cookie表,然后就访问其他路由就会自动携带cookie了,maxAge设置过期时间这里是1个月。如果我们希望修改cookie,是没办法直接修改的,只能重新发送cookie注意要"name"要一致,然后发送新的cookie这里时间为0,去覆盖掉之前的cookie。

4、总结

从最开始简单的数据展示,到现在:

  • ✅ 支持模块化路由
  • ✅ 支持对数据的增删改查
  • ✅ 支持登录验证与登录状态持久化

整个过程让我真正理解了"路由 = 数据表 + 操作方式(增删改查) "的本质。而登录功能 + Cookie,则是保障后台安全访问的核心。

💡 写完这篇博客不仅是一个总结,也是对项目架构认知的提升。如果你也在学习 Node.js 后端,建议从这个小项目入手,循序渐进搭出属于你自己的后台系统。

相关推荐
期待のcode1 天前
MyBatisX插件
java·数据库·后端·mybatis·springboot
华仔啊1 天前
这 10 个 MySQL 高级用法,让你的代码又快又好看
后端·mysql
码事漫谈1 天前
国产时序数据库崛起:金仓凭什么在复杂场景中碾压InfluxDB
后端
上进小菜猪1 天前
当时序数据不再“只是时间”:金仓数据库如何在复杂场景中拉开与 InfluxDB 的差距
后端
盖世英雄酱581361 天前
springboot 项目 从jdk 8 升级到jdk21 会面临哪些问题
java·后端
程序猿DD1 天前
JUnit 5 中的 @ClassTemplate 实战指南
java·后端
Victor3561 天前
Netty(14)如何处理Netty中的异常和错误?
后端
Victor3561 天前
Netty(13)Netty中的事件和回调机制
后端
码事漫谈1 天前
VS Code 1.107 更新:多智能体协同与开发体验升级
后端