• NODE基于express 框架和mongoDB完成session认证 和图片上传删除等功能


    源码地址

    https://gitee.com/zyqwasd/mongdbSession

    本项目的mongodb是本地的mongodb 开启方法可以百度一下 端口是默认的27017

    页面效果

    1. 注册登录页 

     2. 上传的图片 和删除数据库的数据和服务器上的图片

     

     前端代码 因为是个小项目就用原生写了 

    1. 这个是login 页面一个注册模块一个登录模块

    复制代码
     
    
    
    复制代码

     2. 首页代码

    复制代码
     fetch("/api")
        .then(res => res.json())
        .then(res => {
          render(res)
        })
      username.innerHTML = localStorage.getItem("username")
      img.src = localStorage.getItem("avatar")
      function render(arr) {//渲染页面 
        table.innerHTML = arr.map((item, index) => ` 
        
          ${index}
          ${item.username}
          
          
        
        `).join("")
      }
      table.onclick = (e) => {
        if (e.target.nodeName === "BUTTON") {
          const parent = e.target.parentNode.parentNode
          const src = parent.dataset.src
          // 发请求删除对应数据库的内容
          fetch(`/api?id=${parent.id}&src=${src} `, { method: 'delete' })
            .then(res => res.json()).then(res => {
              // 删除对应的tr 
              res.ok && parent.remove()
            })
        }
      }
    复制代码

    后端代码

    1. 因为时间问题就用了express生成器 可以去expresse 官网查看 获取下载我的代码

    连接mongodb

    1. 创建一个配置文件夹config 下载安装mongoose 模块 连接数据库 (一定要先开启数据库)

    const mongoose = require("mongoose");
    // 因为是演示就自己在本地搭了一个数据库
    // 连接好了数据库并且 创建了一个叫users 的数据库
    mongoose.connect("mongodb://127.0.0.1:27017/users")

    2. 在www 文件下引入

       

    // 引入数据库
    require("../config/mongoose")

    3. 因为mongodb的数据自由度高所有配置一个模板来规定数据类型  在model文件夹/userModel

    复制代码
    const mongoose = require("mongoose")
    // 定义数据类型
    const modelType = {
        username: String,
        password: String,
        avatar: String,
    }
    
    const userModel = mongoose.model("user", new mongoose.Schema(modelType));
    
    module.exports = userModel
    复制代码

    配置multer 模块在app.js中的代码

    1.在app 中引入multer模块来处理数据和配置文件下载的路径 

    // 引入multer
    const multer = require("multer")
    // 部署放头像的文件
    const upload = multer({ dest: "public/uploads/" })

    2. 在app 中处理login 上传来的图片把他放入到指定文件夹中  如果想知道如何上传多个文件可以私聊我

    // 处理文件上传数据 single 是上传单个文件 array是上传多个文件
    app.use("/login", upload.single("avatar"), loginRouter);

    配置session 在app.js中代码

    1. 在app.js中引入express-session 和 connect-mongo 

    // 引入session 模块
    const session = require("express-session");
    // 引入  connect-mongo 这个是存储cookie 到mongodb 中自动删除和更新
    const MongoStore = require("connect-mongo")

    2.配置初始化配置session 

    复制代码
    // 配置session 
    app.use(session({
      name: "mySession",
      secret: "session secret",//配置秘钥
      resave: true,//重新设置cookie 值可以重新计时
      saveUninitialized: true,//初始化session  一开始就给服务器发送一个cookie 
      cookie: {
        maxAge: 1000 * 60 * 60, //设置过期时间
        secure: false,//是否在安全模式下就是https 下访问
      },
      rolling: true,//表示在超时前刷新就会从新计时cookie 为false 表示超时前刷新多少次都会按照第一次开始计时
      // 配置cookie 存入到MongoDB 中
      store: MongoStore.create({
        mongoUrl: 'mongodb://127.0.0.1:27017/my_session',//链接数据库
        ttl: 1000 * 60 * 60, //设置过期时间
      })
    }))
    复制代码

    3. 全局拦截认证session

    复制代码
    // 全局拦截session 
    app.use((req, res, next) => {
      if (req.url.includes("login")) return next()
      // 登录成功了就给session挂载一个user属性
      if (req.session.user) {
        // 如果有就放行重新设置session 值
        req.session.myDate = Date.now();
        next()
      } else {
        // 因为我是又有后端渲染又有前端的请求所以我们要判断
        req.url.includes("api") ?
          // 如果是api 就send  ok:1
          res.status(401).send({ ok: 1 })
          // 如果是 页面的请求就跳到login 页面
          : res.redirect("/login")
      }
    })
    复制代码

    处理login页面数据

    1. 在router中的路径处理

    复制代码
    const express = require("express");
    const controller = require('../controller/userController');
    const router = express.Router()
    
    router.get("/", (req, res) => {
        res.render("login")
    })
    
    // 注册来的数据
    router.post("/", controller.create)
    // 登录来的数据
    router.post("/find", controller.find)
    
    module.exports = router
    复制代码

    处理数据响应每一个接口的处理函数 因为代码少就没有多分

    复制代码
    const userService = require("../service/userService")
    const controller = {
        // 创建数据到mongodb中注册页传来的
        async create(req, res) {
            // 数据解构出来
            const { username, password } = req.body
            // 如果上传头像就存储上传来的 
            // 如果没有上传来就走默认头像
            const avatar = req.file ?
                "/uploads/" + req.file.filename :
                "/images/avatar.jpeg";
            // 去service模块创建数据到数据库中
            await userService.create(username, password, avatar);
            // 返回前端数据
            res.send({ ok: 1 })
        },
        async find(req, res) {
            const { username, password } = req.body;
            // 用async  和await 来去数据库查找数据 主要代码在service中
            let data = await userService.find(username, password)
            if (data.length) {
                // 如果验证通过了就设置一个session值
                req.session.user = data[0]
                // 如果找到了 返回前端一个当前登录用户的头像
                res.send({ ok: 1, avatar: data[0].avatar })
            } else {
                res.send({ ok: 0 })
            }
        },
        // 查找所有数据用来渲染主页 显示页面 因为都是异步的所以用了async 和await 
        async findAll(req, res) {
            let data = await userService.findAll()
            res.send(data)
        },
        // 前端发来的删除用户请求
        async delete(req, res) {
            // 把id 和图片的src 结构出来
            const { id, src } = req.query
            // 去删除数据库中的数据
            let data = await userService.delete(id)
            // 去删除本地文件 因为代码少懒得分一个模块了
            await userService.deleteFile(src)
            // 给前端传一个布尔值这个如果删除了就是true 没有就是false
            res.send({ ok: data.acknowledged })
        }
    }
    
    module.exports = controller
    复制代码

    处理数据库和文件夹中的数据

    复制代码
    const userModel = require("../model/userModel")
    // 引入fs 模块 因为是异步所以要用promises
    const fs = require("fs").promises
    const service = {
        // 把数据存储到数据库中
        create(username, password, avatar) {
            // 用我们之前的模板直接来创建数据
            return userModel.create({
                username, password, avatar,
            })
        },
        find(username, password) {
            // 查找数据给前面模块返回回去 条件是传来的值
            return userModel.find({ username, password })
        },
        findAll() {
            // 只获取到["username", "avatar"]两个字段
            return userModel.find({}, ["username", "avatar"])
            // 当然因为数据量少没有搞分页什么的
            // find().count()是获取总的条数
            // sort() 按照什么排序
            // skip ()跳过几条
            // limit() 要几条 
            // 也蛮简单的可以试试
        },
        delete(id) {
            // 删除数据库中的数据
            return userModel.deleteOne({ _id: id })
        },
        async deleteFile(src) {
            // 如果是默认数据 我把数据存储到public /images 中了其他的在uploads 中
            if (src.includes("/images")) return;
            // 因为删除文件没有文件会报错影响服务器 就try catch 处理一下
            try {
                return data = await fs.unlink(`./public/${src}`)
    
            } catch (error) {
                return false
            }
    
        }
    }
    
    module.exports = service
    复制代码

     

  • 相关阅读:
    Transformers基本组件(一)快速入门Pipeline、Tokenizer、Model
    Python的整数是如何实现的
    【咖啡品牌分析】Google Maps数据采集咖啡市场数据分析区域分析热度分布分析数据抓取瑞幸星巴克
    Redis入门与应用
    vite+vue3+ts开发web日语项目,支持主题切换,pinia状态持久化管理
    记录一个奇怪bug
    基于51单片机的孵化环境温湿度监控系统设计
    springboot毕设项目医疗纠纷处理系统zwxts(java+VUE+Mybatis+Maven+Mysql)
    堪称经典,一个非常适合初学者的机器学习实战案例
    IED设备模型
  • 原文地址:https://www.cnblogs.com/qiaomucreate/p/16697678.html