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('退出成功');
};

相关推荐

  1. node环境Vue项目目录结构介绍

    2024-03-15 04:50:04       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-15 04:50:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-15 04:50:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-15 04:50:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-15 04:50:04       20 阅读

热门阅读

  1. C++面试题和笔试题(五)

    2024-03-15 04:50:04       19 阅读
  2. 题记(54)--L1-050 倒数第N个字符串

    2024-03-15 04:50:04       24 阅读
  3. c++特殊类设计

    2024-03-15 04:50:04       19 阅读
  4. 什么是API签名认证?

    2024-03-15 04:50:04       23 阅读
  5. 2024年科技前瞻:AI辅助研发引领未来创新浪潮

    2024-03-15 04:50:04       22 阅读
  6. Android JNI常用API函数介绍

    2024-03-15 04:50:04       21 阅读
  7. 有来团队后台项目-解析10

    2024-03-15 04:50:04       24 阅读
  8. Qt/QML编程之路:线程及Slot的指针传递(47)

    2024-03-15 04:50:04       19 阅读
  9. 2024.3.14 训练记录(16)

    2024-03-15 04:50:04       22 阅读
  10. 大模型prompt提示词如何调优?

    2024-03-15 04:50:04       20 阅读
  11. 【点云】激光点云建图评测

    2024-03-15 04:50:04       21 阅读
  12. OpenAI GPT-4.5 Turbo 泄露,六月或将发布

    2024-03-15 04:50:04       21 阅读