当前位置: 首页 > article >正文

Vue2 + node.js项目

1、Vue2

vue2主要功能包括登入、退出、用户权限、表格的增删改查、文件下载。

Vue2项目地址icon-default.png?t=N7T8https://gitee.com/www6/finance1.git

2、node.js编写后端接口

2.1、项目初始化

后端地址icon-default.png?t=N7T8https://gitee.com/www6/finance-backend.git

创建项目

npm install -g koa-generator  //安装koa-generator
koa2 创建项目名

在utils/index.js封装token

var jwt = require('jsonwebtoken');
const { secret, tokenExpires } = require('../conf');

exports.createToken = (user) => {
  return jwt.sign(user, secret, {
    expiresIn: tokenExpires,
  });
};

exports.vertifyToken = (token) => {
  try {
    var decoed = jwt.verify(token, secret);
  } catch (e) {
  } finally {
    return decoed;
  }
};
exports.getUser = (token) => {
  return jwt.decode(token, secret);
};

响应处理

// 响应处理  app.js
app.context.success = function (data) {
  this.body = {
    code: 20000,
    data,
  };
};
app.context.faild = function (data) {
  this.body = {
    code: 102,
    data,
  };
};
app.context.tokenExpires = function (data) {
  this.body = {
    code: 603,
    data,
  };
};

创建成功之后,接着下一步。

2.2、建立Mysql链接

根目录新建models/db.js文件

var mysql = require('mysql');
const { db } = require('../conf');
var pool = mysql.createPool(db);

exports.query = function(sql,params=[]) {
 if (!params) {
     console.log('当前查询参数没有值,请查看',params);
 }
 return new Promise((resolve,reject)=>{
    pool.getConnection(function (err, connection) {
        if (err) throw err; // not connected!
    
        // Use the connection
        connection.query(sql,params, function (error, results, fields) {
            // 调试log
            console.log(`${sql}==>${params}=数据=>${results}`);
            connection.release();
            // Handle error after the release.
            if (error) {
                console.log('db出现异常:',error)
                return reject(error)
            }
            resolve(results);
    
            // Don't use the connection here, it has been returned to the pool.
        });
    });

 });
}

根目录下新建conf.js文件

exports.db = {
  connectionLimit: 10,
  host: "localhost",
  user: "xxx",
  password: "xxx",
  database: "xxx",
};

exports.secret = "xxx";

exports.tokenExpires = 6000 * 3;

exports.whiteList = ["/user/login", "/user/logout"];

2.3、登入

新建routes/user.js文件

const router = require('koa-router')()
const { doLogin} = require('../controllers/user');

router.prefix('/user')
.post('/login',doLogin)

module.exports = router

新建controllers/user.js文件

const {findUserByAccount} = require('../models/user');
const { createToken, vertifyToken, getUser } = require('../utils');

exports.doLogin = async (ctx, next) => {
  let { account, password } = ctx.request.body;

  if (!account || !password) {
    return ctx.faild('必须传递用户名和密码');
  }

  const res = await findUserByAccount(account);

  if (res.length === 0) {
    return ctx.faild('用户名或者密码不存在');
  }

  let user = res[0];
  if (user.password != password) {
    return ctx.faild('用户名或者密码不存在');
  }
  const saveUser = {
    id: user.id,
    account: user.account,
    // 权限
    type: user.role_id,
  };

  // 生成token
  const token = createToken(saveUser);
  ctx.success({
    token,
  });
};


;

新建models/user.js文件

const { query } = require('../models/db');

exports.findUserByAccount = account => query('select * from user where account = ?',[account]);

2.4、中间件处理

const { whiteList } = require('../conf');
const { vertifyToken, getUser } = require('../utils');

exports.checkLogin = async (ctx, next) => {
  // 非登录、退出
  // 需要检查的
  if (!whiteList.includes(ctx.url)) {
    const { token } = ctx.headers;
    let tokenIndex = ctx.blackTokenList.indexOf(token);
    // 验证token
    if (!vertifyToken(token)) {
      // 弹出这个元素,不允许访问,重新获取token
      ctx.blackTokenList.splice(tokenIndex, 1);
      return ctx.tokenExpires('无效token,请登录再试!');
    } else {
      // 黑名单: 退出后的token
      if (tokenIndex !== -1) return ctx.tokenExpires('token已经失效');
      // 解析token并存储到ctx的上面, ctx.state 本次请求的共享数据
      ctx.state.user = getUser(token);
    }
  }

  await next();
};
// app.js全局引入

const { responseHandler, checkLogin } = require('./middlewares');
app.use(checkLogin);

2.5、用户详情

router.prefix('/user')
.get('/info',getInfo)

exports.getInfo = async (ctx) => {
  const user = ctx.state.user;
  if (!user) return ctx.faild('用户信息获取失败!');
  const { id } = user;
  const res = await findUserById(id);
  const dbUser = res[0];

  if (!dbUser) return ctx.faild('用户信息不存在,或者已经被删除');

  ctx.success({
    info: '获取成功!',
    roles: [{ name: dbUser.role_name }],
  });
};

exports.findUserById = id => query('select * from user where id = ?',[id]);

2.6、退出

router.prefix('/user')
.post('/logout',logout)


// 退出后的token  在app.js全局添加
app.context.blackTokenList = [];


exports.logout = async (ctx) => {
  ctx.blackTokenList.push(ctx.headers.token);
  return ctx.tokenExpires('退出成功');
};


http://www.kler.cn/a/272397.html

相关文章:

  • ARP 表、MAC 表、路由表、跨网段 ARP
  • 语音技术在播客领域的应用(2)
  • jlatexmath-android如何实现自定义渲染字符
  • 计算机毕业设计Python+卷积神经网络租房推荐系统 租房大屏可视化 租房爬虫 hadoop spark 58同城租房爬虫 房源推荐系统
  • TTL 在 Redis 缓存中的作用
  • 电力场景红外测温图像绝缘套管分割数据集labelme格式2436张1类别
  • 大语言模型相关工具使用链接
  • 异常GPT:使用LVLMs检测工业异常
  • 【金三银四】掌趣科技24.3.7 H项目 服务端开发笔试题
  • C++面试100问(十)
  • 【K8s】肿么办??Kubernetes Secrets并不是Secret哟!!
  • 数据结构概述
  • Spring6--IOC反转控制 / 基于XML管理bean
  • 数据结构之双向链表
  • Sklearn K-均值算法
  • python提取身份证中的生日和性别
  • 远程办公、企业内网服务器的Code-Server上如何配置使用CodeGeeX插件
  • 图解Kafka架构学习笔记(一)
  • C语言经典面试题目(十八)
  • unityprotobuf自动生成C#
  • fastapi 的css js文件地址修改
  • 第 126 场 LeetCode 双周赛题解
  • 设计原则、工厂、单例模式
  • 程序人生——Java异常使用建议
  • el-select使用filterable下拉无法关闭得问题
  • react03