“好事”文章推荐:《Docker与Kubernetes实现自动化部署!》
文章地址:https://cloud.tencent.com/developer/article/2471047
一直想学习下Docker 和 Kubernetes。这篇文章介绍了Docker 和 Kubernetes的核心概念,通过一个具体的实践案例,详细介绍如何使用 Java 开发一个简单的 Web 应用,并将其容器化部署到 Kubernetes 集群中
登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见小程序登录。
services/ws.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
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
}
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过期
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().m
还是拿bookapi为例
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
})
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
}
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')
});
require('./user');
require('./book');
require('./records');
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 删除。