Koa + JWT + 登录+ 后台验证

5 篇文章 0 订阅
4 篇文章 0 订阅

token 方法封装 — jwt-token.js

const jwt = require('jsonwebtoken'); // 用于签发、解析`token`
const jwtSecret = 'jwtSecret'
const tokenExpiresTime =  60 * 60 * 4 // 4小时
/* 获取一个期限为4小时的token */
function getToken(payload = {}) {
    return jwt.sign(payload, jwtSecret, { expiresIn: tokenExpiresTime  });
}

/* 通过token获取JWT的payload部分 */
function getJWTPayload(token) {
    // 验证并解析JWT
    return jwt.verify(token.split(' ')[1], jwtSecret);
}

/* 通过token获取JWT的payload部分 */
function getJWTPayComplete(token) {
    // 验证JWT
    return jwt.verify(token.split(' ')[1], jwtSecret, {
        complete: true
       });
}

function tokenVerify(token){
    if (token) {
        jwt.verify(token, jwtSecret, (err, decoded) => {
        if (err) {
            switch (err.name) {
            case 'JsonWebTokenError':
                res.status(403).send({ code: -1, msg: '无效的token' });
                break;
            case 'TokenExpiredError':
                res.status(403).send({ code: -1, msg: 'token过期' });
                break;
            }
        }
        })
    }
}


module.exports = {
    getToken,
    getJWTPayload,
    getJWTPayComplete
}

用户登录注册

db —mysql.js
const mysql = require('mysql');
const {MYSQL_CONF} = require('../conf/db');

// 创建 链接对象
const con = mysql.createConnection({
    ...MYSQL_CONF
});

// 开始链接
con.connect();

// // 添加执行 sql 函数
function exec(sql) {
    return new Promise((resolve,reject)=>{
        con.query(sql,(err,result)=>{
            if (err) {
                reject(err);
                return
            }
            resolve(result)
        })
    })
}

const pool = mysql.createPool({
    ...MYSQL_CONF
});
let loginGet = (req) =>{
    return new Promise((resolve,reject)=>{
        pool.getConnection((err, connection) => {
            let paramValue = paramList(req);
            if(err){
                console.log("建立连接失败", err);
                reject(err);
            }else {
                connection.query(sql['admin_user'].queryById, [...paramValue], (err, result) => {
                    resolve(result)
                    // 释放连接
                    connection.release();
                });
            }
        })
    })
}

/**
 * @description 新增一条数据
 * @param  {str} table 数据库表的名称
 * @param  {obj} req 插入的数据
 * @param  {obj} res 接口函数中的res对象
 * @param  {obj} next 接口函数中的next对象
 */
 let dbAdd = (table, req, res, next) => {
    pool.getConnection((err, connection) => {
        let paramValue = paramList(req);
        connection.query(sql[table].insert, [...paramValue], (err, result) => {
            if (result) { result = "add"; }
            // 以json形式,把操作结果返回给前台页面
            json(res, result, err);
            // 释放连接
            connection.release();
        });
    });
};

/**
 *@description 删除一条数据
 @param 同abAdd
 */
let dbDelete = (table, req, res, next) => {
    let paramValue = paramList(req);
    pool.getConnection((err, connection) => {
        connection.query(sql[table].delete, [...paramValue], (err, result) => {
            if (result.affectedRows > 0) {
                result = "delete";
            } else {
                result = undefined;
            }
            json(res, result, err);
            connection.release();
        });
    });
};

/**
 *@description 修改一条数据
 @param 同abAdd
 */
let dbUpdate = (table, req, res, next, id) => {
    let paramValue = paramList(req);
    console.log(req, paramValue);
    pool.getConnection((err, connection) => {
        // let sqls = `UPDATE ${table} SET name='${req.name}', file_number='${req.file_number}', edit_time='${req.edit_time}', remark='${req.remark}' WHERE bid=${req.bid}`;
        connection.query(sql[table].update, [...paramValue, id], (err, result) => {
            console.log('result', err)
            if (result.affectedRows > 0) {
                result = "update";
            } else {
                result = undefined;
            }
            json(res, result, err);
            connection.release();
        });
    });
};

/**
 *@description 查找一条数据
 @param 同abAdd
 */
let dbQueryById = (table, req, res, next) => {
    let paramValue = paramList(req);
    pool.getConnection((err, connection) => {
        connection.query(sql[table].queryById, [...paramValue], (err, result) => {
            if (result != "") {
                var _result = result;
                result = {
                    result: "select",
                    data: _result,
                };
            } else {
                result = undefined;
            }
            json(res, result, err);
            connection.release();
        });
    });
};

/**
 *@description 查找全部数据
 @param 同abAdd
 */
let dbQueryAll = (table, req, res, next) => {
    pool.getConnection((err, connection) => {
        connection.query(sql[table].queryAll, (err, result) => {
            if (result && result !== "") {
                var _result = result;
                result = {
                    result: "selectall",
                    data: _result,
                };
            } else {
                result = undefined;
            }
            json(res, result, err);
            connection.release();
        });
    });
};

/**
 * 分页list
 */
let queryList = (table, req, res, next) => {
        let data = req.query,
            pageSize = data.pageSize*1 || 10,
            pageIndex = data.pageIndex*1 || 1;
        pool.getConnection((err, connection) => {
            connection.query(`SELECT * FROM ${table} limit ${(pageIndex-1)*pageSize},${pageSize}`, (err, result) => {
                connection.query(`SELECT count(*) total FROM ${table}`, (err1, result1) => {
                    // console.log('result1', result1);
                    if (result && result !== "") {
                        var _result = result;
                        result = {
                            status: 200,
                            msg: "查找成功",
                            data: _result,
                            total: result1[0]['total']
                        };
                    } else {
                        result = undefined;
                    }
                    json(res, result, err);
                    connection.release();
                })
        });
    });
};

/**
 * @description 遍历数据的值
 * @param {obj} obj 包含参数的对象
 * */
let paramList = (obj) => {
    let paramArr = [];
    for (let key in obj) {
        if (obj[key]) {
            paramArr.push(obj[key]);
        }
    }
    return paramArr;
};


module.exports = {
    exec,
    escape: mysql.escape
}

routes — user.js
const router = require('koa-router')();
const koaJwt = require('koa-jwt') //路由权限控制
const {login} = require('./../controller/user')
const {SuccessModel,ErrorModel} = require('./../model/resModel')
const { getToken , getJWTPayload} = require('../utils/jwt-token')
//秘钥
const jwtSecret = 'jwtSecret'

router.prefix('/api')

// 登录
router.post('/user/login',async (context,next)=>{
    const {username,password} = context.request.body;
    if( username == '' || password == ''){
        context.body = new ErrorModel(null,"请填写账号和密码")
    }else{
        const userData = await login(username,password);
        if (userData && userData.username) {
            context.session.username = userData.user;
            context.session.password = userData.password;
            const token =  getToken({...userData}) // token 加密
            context.body = new SuccessModel({token},'登录成功')
        }else {
            context.body = new ErrorModel(userData,"密码错误,请重新登录")
        }
    }
    
})

// 获取用户信息
router.get('/user/userInfo',async (context,next)=>{
    const token = context.header.authorization
    const payload = getJWTPayload(token) // token解密
    context.body = new SuccessModel(payload)
   
})

// 注册
router.post('/user/register',async (context,next)=>{
    const {username,password} = context.request.body;
    // const token = context.header.authorization
    // const payload = getJWTPayload(token)
    // context.body = new SuccessModel(payload)

   
})


module.exports = router

controller —user.js
const {exec,escape} = require('../db/mysql')
const {genPassword,getNewTime} = require('../utils/cryp')
const {ErrorModel} = require('../model/resModel');
const login = async (userName,password)=>{
    userName = escape(userName);
    // password = genPassword(password)
    // password = escape(password);
    password = password
    let sql = `SELECT * FROM sys_user WHERE username=${userName} and password=${password}`
    const userData = await exec(sql);
    console.log(JSON.stringify(userData))
    let data = {}
    if(userData){
        data = userData[0]
    }else{
        data = {}
    }
    return data
}

module.exports = {
    login
}

app.js

const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')
const session = require('koa-generic-session')
const redisStore = require('koa-redis')
const path = require('path');
const fs = require('fs')
const koaJwt = require('koa-jwt') //路由权限控制
const morgan = require('koa-morgan')
const cors = require('koa2-cors'); //跨域处理

// const ENV = process.env.NODE_ENV;
// if (ENV !=='production') {
//     // 开发和测试
//     app.use(morgan('dev'));
// }else {
//     // 线上
//     const logFileName = path.join(__dirname, 'logs', 'access.log');
//     const writeStream = fs.createWriteStream(logFileName,{
//         flags: 'a'
//     })
//     app.use(morgan('combined',{
//         stream: writeStream
//     }));
// }
app.use(morgan('dev'));



const index = require('./routes/index')
const blog = require('./routes/blog')
const user = require('./routes/user')
const menu = require('./routes/menu')
const {REDIS_CONF} = require('./conf/db')
app.use(cors()); //放到route前面


// error handler
// onerror(app)

// middlewares
app.use(bodyparser({
  enableTypes:['json', 'form', 'text']
}))
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))

app.use(views(__dirname + '/views', {
  extension: 'pug'
}))

// logger
app.use(async (ctx, next) => {
  // const start = new Date()
  // await next()
  // const ms = new Date() - start
  // console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
  // 添加解决跨域
  ctx.set('Access-Control-Allow-Origin', '*');
  ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, authorization, Accept, X-Requested-With , yourHeaderFeild');
  ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  // if (ctx.method == 'OPTIONS') {
  //   ctx.body = 200; 
  // } else {
  //   await next();
  // }
  await next();
})

//jwt
//秘钥
const jwtSecret = 'jwtSecret'
const tokenExpiresTime = 1000 * 60 * 60 * 24 * 7

// Custom 401 handling if you don't want to expose koa-jwt errors to users
app.use(function(ctx, next){
    return next().catch((err) => {
        if (401 == err.statusCode ) {// token 失效
            ctx.code = 401;
            ctx.body = {
              code:401,
              data:null,
              message:"'token 失效请重新登录"
            };
        } 
        else {
            throw err;
        }
    });
});

app.use(koaJwt({secret:jwtSecret}).unless({
    path: ['/api/user/login','/api/user/register'] //除了这些请求地址,其他的URL都需要验证
}))




// session 配置
app.keys = ['Jin_jin#']
app.use(session({
//    配置cookie
    cookie: {
        path: '/',
        httpOnly: true,
        maxAge: 24*60*60*1000
    },
    // store: redisStore({
    //     all: `${REDIS_CONF.host}:${REDIS_CONF.port}`
    // })
}))

// routes
app.use(index.routes(), index.allowedMethods())
app.use(blog.routes(), blog.allowedMethods())
app.use(user.routes(), user.allowedMethods())
app.use(menu.routes(), menu.allowedMethods())


// error-handling
app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
});

//启动服务器
app.listen(3000, () => {
  console.log('服务器启动成功')
  console.log('http://127.0.0.1:3000')
});


module.exports = app

web端登录 验证

前端登录成功后 拿到Token 像请求头传参数

 config.headers.common['Authorization'] = 'Bearer ' + getToken(); // 存在Bearer 后面存在空格***
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值