koacms(四)JWT安装,后台登录接口逻辑

1、安装jwt

npm i jsonwebtoken bcryptjs 
npm i nanoid@3.3.6

2、config文件夹下新建index.js文件

const config = {
    jwt: {
        secret: 'urcq4yom', // jwt密钥
        expiresIn: 60*60*262820
    },
    bcrypt: {
      saltRounds: 12 // 生成salt迭代次数
    },
    crypto: {
      JOINSTR: 'nm9sinr9' // md5拼接字符串
    },
    password:{
        salt: 'r6pjidD6dpkKYY7U'
    },
    // 图形验证码
   captcha:{
      size: 4, // 验证码长度
      ignoreChars: '012oOiILl', // 验证码字符中排除 0o1i
      noise: 2, // 干扰线条的数量
      fontSize: 52,
      color: true, //开启文字颜色
      // background:"#000",//背景色
      width: 102,
      height: 38,
      time: 2*60,
    }
  }
  
  module.exports = config

3、在utils文件夹下新建verify.js文件

const jwt = require('jsonwebtoken');
const config = require('../config');
const { LoginFailure } = require('../model/resModel')
// 生成token
const sign = (data) => {
	return jwt.sign(data, config.jwt.secret, {
		expiresIn: config.jwt.expiresIn,
	});
};

// 验证token
const verify =async (ctx, next) => {
	let authorization = ctx.headers.authorization || ctx.headers.Authorization || ctx.request.body.token || ctx.request.query.token || '';
	let token = '';
	if (authorization.includes('Bearer')) {
		token = authorization.replace('Bearer ', '');
	} else {
		token = authorization;
	}
	try {
		const res = jwt.verify(token, config.jwt.secret)
		ctx.req.authData = res
		await next();
	} catch(error) {
		 ctx.body = new LoginFailure('token验证失败',error)
	}
	
	
	// });
};

module.exports = {
	sign,
	verify,
};

4、在utils文件夹下新建cryp.js文件

const crypto = require('crypto') // node 自带
const bcrypt = require('bcryptjs') // 需安装依赖 npm i bcryptjs
const { bcrypt: bcryptConfig, crypto: cryptoConfig } = require('../config')

// md5加密
function md5(v) {
  const { JOINSTR } = cryptoConfig
  return crypto.createHash('md5').update(v + JOINSTR).digest('hex')
}

// 密码加密
function encryptPassword(password) {
  const { saltRounds } = bcryptConfig
  const pwdEnCode = md5(password)
  const salt = bcrypt.genSaltSync(saltRounds)
  return bcrypt.hashSync(pwdEnCode, salt)
}

// 密码验证
function verifyPassword(inputPwd, userPwd) {
  const pwdEnCode = md5(inputPwd)
  return bcrypt.compareSync(pwdEnCode, userPwd)
}

module.exports = {
  encryptPassword,
  verifyPassword
}

5、在controller新建admin.js文件

const db = require('../config/knex')
const { encryptPassword,verifyPassword } = require('../utils/cryp')
const { sign } = require('../utils/verify')
const { SuccessModel, ErrorModel } = require('../model/resModel')
const adminModel = require('../model/adminModel') 
class AdminController {

    // 登录
    async login(ctx, next) {
        const { username, password } = ctx.request.body
        const res = await adminModel.getInfo({username})
        if(res.length===0) return ctx.body = new ErrorModel('没有该账号')
        if (!verifyPassword(password + res[0].salt,res[0].password))  return ctx.body = new ErrorModel('密码错误')
        delete res[0].password
        delete res[0].salt
        res[0].token = sign({ id: res[0].id,username: res[0].username,group_id:res[0].group_id })

        try {
            const time=new Date().getTime() / 1000
            const updateRes = await adminModel.update(res[0].id,{token: res[0].token,login_time:time})
            if(!updateRes) return ctx.body = new ErrorModel('登录错误')
            ctx.body = new SuccessModel('登录成功',res[0])
        } catch (error) {
            return ctx.body = new ErrorModel(error)
        }
           
        
    }
    
}
module.exports = new AdminController()

6、在model文件夹下新建adminModel.js文件

const db = require('../config/knex')

class cms_adminModel {
    async create(data){
        return await db.create('cms_admin',data)
    }

    async getInfo(where){
      
        return await db.knex('cms_admin')
        .join('cms_auth_group', 'cms_admin.group_id', 'cms_auth_group.id')
        .select('cms_admin.*','cms_auth_group.title','cms_auth_group.rules','cms_auth_group.roleCode')
        .where(where)
    }
    
    async update(id,data){
        return await db.update('cms_admin',id,data)
    }

    async delete(id){
        return await db.remove('cms_admin',id)
    }

    async batchDelete(ids){
        return await db.batchDelete('cms_admin',ids)
    }

    async page(page=1,size=10, where={},orderBy='',fields='*'){
        const offset = (page - 1) * size;
        const order = orderBy ? order : ['id' ,'desc'];
        const query =  db.knex('cms_admin').count('* as total')
        .where('username', 'like',`%${where.username}%`)
        .where('nickname', 'like',`%${where.nickname}%`)
        .where('mobile', 'like',`%${where.mobile}%`)
        
        const [countResult, rows] = await Promise.all([
            query,
            db.knex('cms_admin')
                .select(fields)
                .where(where)
                .orderBy(order[0],order[1])
                .offset(offset)
                .limit(size)
            ]);


        const count = countResult[0].total;
        const pageData = {
            page:Number(page),
            size,
            count,
            list: rows
        };
    
        return pageData;
    }

    async list(where=[],fields='*'){
        return await db.getList('cms_admin',where,fields)
    }
}

module.exports = new cms_adminModel()

7、修改routes文件夹下的admin.js

const router = require('koa-router')()
const jwt = require('../../utils/verify')
const AdminController = require('../../controller/admin')

router.prefix('/api')

router.post('/system/user/login', AdminController.login)

module.exports = router

8、app.js中引入admin路由


const admin=require('./routes/admin/admin.js');

app.use(admin.routes(), admin.allowedMethods())

9、在数据库cms_admin新建一条数据,用来测试登录的接口

//数据库字段对应值 账号:admin 密码:123456
{
    username:'admin',
    nickname:'Admin',
    password: '$2a$12$YPckpLQYEP1b5u2X/v5MG.y38u07TvCsd2tXqMxAZ72XTiM2RU65O',
    salt: 'qONFQbo2AuApbnVLyWmd8',
    group_id: 1
}

10、在数据库cms_auth_group新建一条数据,

{
    title:'超级管理员',
    status:1 
}

11、使用apifox测试接口,post请求

http://localhost:3008/api/system/user/login

{
    "username": "admin",
    "password": "123456"
}

结果返回:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值