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
}
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
}
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
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
}
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
前端登录成功后 拿到Token 像请求头传参数
config.headers.common['Authorization'] = 'Bearer ' + getToken(); // 存在Bearer 后面存在空格***