前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >前端小白玩转koa(三)

前端小白玩转koa(三)

原创
作者头像
一起重学前端
修改2024-11-28 09:46:27
修改2024-11-28 09:46:27
870
举报

“好事”文章推荐:《Docker与Kubernetes实现自动化部署!》

文章地址:https://cloud.tencent.com/developer/article/2471047

一直想学习下Docker 和 Kubernetes。这篇文章介绍了Docker 和 Kubernetes的核心概念,通过一个具体的实践案例,详细介绍如何使用 Java 开发一个简单的 Web 应用,并将其容器化部署到 Kubernetes 集群中

接上一篇

微信小程序授权code&权限

微信小程序授权code

登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见小程序登录。

services/ws.js

代码语言:js
复制
const util = require('util')
const axios = require('axios')
const { User } = require('@models/user')
const { generateToken } = require('@core/util')
const { Auth } = require('@middlewares/auth')

class WXManager {
    static async codeToToken(code) {
        const url = util.format(global.config.wx.loginUrl, global.config.wx.appID, global.config.wx.appSecret, code)

        const result = await axios.get(url)
        if(result.status !== 200) {
            throw new global.errs.AuthFailed('openid获取失败')
        }
        const errcode = result.data.errcode
        const errmsg = result.data.errmsg
        if(errcode) {
            throw new global.errs.AuthFailed('openid获取失败:' + errmsg)
        }

        let user = await User.getUserByOpenid({openid: result.data.openid})
        if(!user) {
            user = await User.registerByOpenid(result.data)
        }

        return generateToken(user.id, Auth.USER)
    }
}

module.exports = {
    WXManager
}
权限校验中间件

middlewares/auth.js

代码语言:js
复制
const basicAuth = require('basic-auth')
const jwt = require('jsonwebtoken')

class Auth {
    constructor(level) {
        this.level = level || 1
        Auth.USER = 8
        Auth.ADMIN = 16
        Auth.SUPER_ADMIN = 32
    }

    get m() {
        return async (ctx, next) => {
            const userToken = basicAuth(ctx.req)
            let errMsg = 'token不合法'

            if(!userToken || !userToken.name) {
                throw new global.errs.Forbidden(errMsg)
            }
            try {
                var decode = jwt.verify(userToken.name, global.config.security.secretKey)
            } catch (error) {
                if(error.name == 'TokenExpiredError') {
                    errMsg = 'token已过期'
                }
                throw new global.errs.Forbidden(errMsg)
            }

            if(decode.scope < this.level) {
                errMsg = '权限不足'
                throw new global.errs.Forbidden(errMsg)
            }

            ctx.auth = {
                uid: decode.uid,
                scope: decode.scope
            }

            await next()
        }
    }

    static verifyToken(token) {
        try {
            jwt.verify(token, global.config.security.secretKey)
            return true
        } catch (error) {
            return false
        }
    }
}

module.exports = {
    Auth
}

jwt token 处理

通过uid 和 用户权限标识生成token
代码语言:js
复制
const jwt = require('jsonwebtoken')

const generateToken = function (uid, scope) {
    const secretKey = global.config.security.secretKey
    const expiresIn = global.config.security.expiresIn
    const token = jwt.sign({
        uid,
        scope
    }, secretKey, {
        expiresIn
    })
    return token
}

在上面的class Auth中通过basicAuth获取请求头中的token,再通过 jwt.verify获取权限、判断token过期

代码语言:js
复制
 const userToken = basicAuth(ctx.req)
 var decode = jwt.verify(userToken.name, global.config.security.secretKey)
...
 try {
                var decode = jwt.verify(userToken.name, global.config.security.secretKey)
            } catch (error) {
                if(error.name == 'TokenExpiredError') {
                    errMsg = 'token已过期'
                }
                throw new global.errs.Forbidden(errMsg)
            }
...
new Auth 应用

使用中间件new Auth().m

还是拿bookapi为例

代码语言:js
复制
router.post('/getRecords', new Auth().m, getValidateParams('POST', getRecordSchema), async (ctx, next) => {
    const records = await Records.getRecords(ctx.auth.uid, ctx.request.body.type);
    ctx.body = records
})

sequelize 操作数据库

配置db.js
代码语言:js
复制
const Sequelize = require('sequelize')
const {
    dbName,
    host,
    port,
    user,
    password
} = require('../config/config').database

const sequelize = new Sequelize(dbName, user, password, {
    dialect: 'mysql',
    host,
    port,
    logging: true,
    timezone: '+08:00',
    define: {
        timestamps: true,
        paranoid: true,
        createdAt: 'created_at',
        updatedAt: 'updated_at',
        deletedAt: 'deleted_at',
        underscored: true
    }
})

sequelize.sync({
    force: false
})

module.exports = {
    sequelize
}
自动建表
代码语言:js
复制
require('module-alias/register')

const Koa = require('koa');
const path = require('path');
const bodyParser = require('koa-bodyparser');
const static = require('koa-static');

const catchError = require('@middlewares/exception');
const InitManager = require('@core/init');

// 自动建表
require('@models/index');

const app = new Koa();

// 全局错误处理
app.use(catchError);
// 使用ctx.body解析中间件 ctx.request.body
app.use(bodyParser());
// 静态资源
app.use(static(path.join(__dirname, './static')))
// 注册 中间键 上下文ctx 洋葱模型

// 异步 Promise
InitManager.initCore(app);

app.listen(3000, () => {
    console.log('启动 3000')
});
@models/index.js
代码语言:js
复制
require('./user');
require('./book');
require('./records');
Book Model
代码语言:js
复制
const { sequelize } = require('@core/db')

const { Sequelize, Model } = require('sequelize')

class Book extends Model {
    static async getBookByOpenid({openid, uid}) {
        const book = await Book.findOne({
            where: {
                openid,
                uid
            }
        })
        return book
    }
    static async createBook({openid, uid}) {
        const book = await Book.findOne({
            where: {
                openid,
                uid
            }
        })
        if(book) {
            throw new global.errs.AuthFailed('账本已存在')
        }
        return await Book.create({openid, uid})
    }
}

Book.init({
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    isDefault: {
        type: Sequelize.BOOLEAN,
        defaultValue: true
    },
    isAuto: {
        type: Sequelize.BOOLEAN,
        defaultValue: true
    },
    name: {
        type: Sequelize.STRING(64),
        defaultValue: '默认账本'
    },
    uid: {
        type: Sequelize.STRING(64),
        unique: true
    },
    openid: {
        type: Sequelize.STRING(64),
        unique: true
    },
    status: {
        type: Sequelize.INTEGER,
        defaultValue: 0
    }
}, {
    sequelize,
    tableName: 'book'
})

module.exports = {
    Book
}

到这里使用koa 基本就实现记账c端的api node代码已开源,可以提供给大家学习~欢迎指导

未完待续,持续更新中...

感谢关注点赞评论~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接上一篇
    • 微信小程序授权code&权限
      • 微信小程序授权code
      • 权限校验中间件
    • jwt token 处理
      • 通过uid 和 用户权限标识生成token
      • new Auth 应用
    • sequelize 操作数据库
      • 配置db.js
      • 自动建表
      • @models/index.js
      • Book Model
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档