irpas技术客

Node.js + Vue.js 全栈开发极简后台管理_XiaoJia913_node vue 全栈

未知 6393

文章目录 前言一、环境搭建和工具安装1.1 nodejs1.2 mongodb 二、项目初始化1.搭建服务器2.初始化Vue 三、功能拓展登录功能登录接口登录界面


前言

最近学了Express,感觉还蛮有意思的,自己动手搭建了一个极简的后台管理,整理一下项目开发以及更新一下许久不使用的博客。


提示:需要搭建环境和工具安装(nodejs,npm,mongodb)

一、环境搭建和工具安装 1.1 nodejs

Nodejs 安装

1.2 mongodb

MongoDB安装及环境配置

二、项目初始化

先看看项目的基本结构,黄色框框中是后台管理的ui,红色框框中是服务端;

1.搭建服务器

1.1 新建名为 server 的的文件夹,在终端输入以下命令:

初始化 npm npm init -y安装express npm install express -S安装nodemon npm install -g nodemon创建并设置为启动文件 index.js

启动服务器时输入 nodemon index.js

1.2 配置项目所需中间件和插件:

跨域 Cors npm install cors

请求日志 morgan npm install morgan

数据验证 express-validator npm install express-validator

加密 crypto npm install crypto

2.初始化Vue

本项目是Vue3.0版本,需要升级vue:

升级Vue版本 npm install @vue/cli -g创建Vue项目 vue create [项目名]进入项目路径下 执行 npm install 三、功能拓展
登录功能 登录逻辑: - 用户名、密码验证成功后(前端) 后端签发token返回给前端 - 前端将token保存到本地存储or服务器(localStorage || Cookie) - 每次请求前,通过axios请求拦截器,统一发送token - 通过vue导航守卫,和axios响应拦截器,统一保护页面 登录接口

一般请求方法有GET,POST,DELETE,PUT;为了安全起见,登录请求方法我们使用POST。 当然还需要在启动页面,也就是index.js中配置引用这个路由;这里推荐postman对我们的接口请求进行测试是否创建成功。

const express = require('express') const app = express() const router = require('/router/user.js') app.use(router)

连接数据库,安装MongoDB给express的特有的mongoose中间件

安装mongoose npm install mongoose配置和连接数据库 const mongoose = require("mongoose"); /** 27017 是我们安装配置MongoDB的文件中的端口 vue-admin 是你想创建的数据库名称,可以根据自己情况修改 */ mongoose.connect('mongodb://localhost:27017/vue-admin', { maxPoolSize: 50, wtimeoutMS: 2500, }) const db = mongoose.connection; db.on("error", (err) => { //监听数据库连接失败 console.log("数据库连接失误:", err); }); db.once("open", () => { //数据库连接成功 console.log("数据库连接成功"); }); //创建数据模型 module.exports = { User: mongoose.model("User", require("./user")), }; 创建用户表 //用户模型 user.js const mongoose = require("mongoose"); const userSchema = new mongoose.Schema({ // 数据表属性 }); module.exports = userSchema;

以上是最基础的,后续还要对接口的控制层和数据验证进行封装:

密码加密 MD5 // md5.js //需要安装crypto var crypto = require('crypto') module.exports = (str)=> { return crypto.createHash('md5').update("jiami"+str).digest('Hex') } 数据验证 // validate.js const { validationResult } = require('express-validator') module.exports = (validations) => { return async (req, res, next) => { await Promise.all(validations.map((validation) => validation.run(req))) const errors = validationResult(req) if (errors.isEmpty()) { return next() } res.status(400).json({ errors:errors.array() }) } } // "validator/user.js" //关于用户的验证 const { body } = require("express-validator"); const validate = require("../middleware/validate"); const { User } = require("../model"); const md5 = require('../utils/md5') exports.login = [ validate([ body("email") .notEmpty() .withMessage("邮箱不能为空") .isEmail() .withMessage("邮箱格式错误"), body("password").notEmpty().withMessage("密码不能为空"), ]), validate([ //上面验证成功,检验是否存在此用户 body("email").custom(async (email, { req }) => { const user = await User.findOne({ email }).select([ "username", "email", "image", "password", ]); if (!user) { return Promise.reject("该用户不存在"); } req.user = user; }), ]), validate([ //验证密码是否与数据库存储的相同 body("password").custom(async (password, { req }) => { console.log(req.user.password); console.log(md5(password)); if (md5(password) !== req.user.password) { return Promise.reject("密码不正确"); } }), ]), ]; 登录控制层 user.js // user.js const { User } = require('../model') //名为User数据表 const jwt = require('../utils/jwt') // jsonwebtoken 令牌token // token的秘钥 https://`/ //const { jwtSecret } = require('../config/config.default') const jwtSecret = 'uuid' exports.login = async(req, res, next) => { try { const user = req.user.toJSON() if (user) { const token = await jwt.sign( { userId: user._id, }, jwtSecret, { //expiresIn: 60 * 60 * 24, // token有效期24hour expiresIn: 30 // 一分钟 } ); delete user.password res.status(200).json({ ...user, token, }); } else { return res.status(400).send('登录失败') } } catch (err) { next(err) } } 连接数据库 model层 //用户模型 const mongoose = require("mongoose"); const md5 = require('../utils/md5') //加密md5 这个需要安装 const userSchema = new mongoose.Schema({ username: { type: String, required: true, }, email: { type: String, required: true, }, password: { type: String, select: false, set:(value) => md5(value), required: true, }, image: { type: String, default: null, }, }); module.exports = userSchema; 登录界面 登录界面有一下几点: -axios请求的二次封装 -令牌token的获取与存放位置(js-cookie) -store存储token状态

想必大家都不会不熟悉Axios,这可是在发送请求中发挥重大作用的轻量级库;想使用它,那我们必须得先安装它。 npm install axios -S

封装axios //server.js import axios from 'axios' //import store from '@/store' // import { getToken } from './auth'; //import { Message } from 'element-ui'; const service = axios.create({ //baseURL: "http://localhost:3000/api", //vue.config.js 配置跨域的同时要关掉这里的 baseURL: process.env.VUE_APP_BASE_API, timeout: 5000, }); //请求拦截器 service.interceptors.request.use(config => { config.headers.get['Content-Type'] = "application/json;charset=utf-8", config.headers.post['Content-Type'] = 'application/x-www-form-urlencoded' /* const token = store.getters.token if (token) { config.headers["Authorization"] = "Bearer " + token } */ //console.log(token); return config }, error => { error.message = error return Promise.reject(error) }); //响应拦截器 service.interceptors.response.use(response => { return Promise.resolve(response) }, err => { return err }); export default service; 封装http请求 //封装请求方法 //http.js import service from './service' const http = { get(url, params) { const config = { method: "get", url: url, }; if (params) config.data = params; return service(config); }, put(url, params) { const config = { method: "put", url: url, }; if (params) config.params = params; return service(config); }, post(url, params) { const config = { method: "post", url: url, }; if (params) { config.data = params; } return service(config); }, delete(url, params) { const config = { method: "delete", url: url, }; if (params) config.params = params; return service(config); }, }; export default http 封装api // api.js import http from '../utils/http' //用户登录 export function login(data){ return http.post(`[跨域代理]/login`, data); } 将服务端发送到前端的令牌token保存到store中。 const actions = { // 登录 login({ commit }, userInfo) { const { email, password } = userInfo; return new Promise((resolve, reject) => { login({ email: email.trim(), password: password }) .then((res) => { const token = res.data.token; if (token !== '') { commit('set_token', token) setToken(token) } else { setToken(''); } resolve(); }) .catch((error) => { reject(error); }); }); }, } 调用登录接口 this.$store.dispatch('user/login', this.loginForm).then(() => { setTimeout(() => { this.$message({ message:"登录成功", type:'success' }) }, 1000); }).catch(err=>{ console.log(err) })

完整代码在 点击Github 仓库中


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #node #Vue #全栈 #这是你第一次使用 #Markdown编辑器 #所展示的欢迎页