Use koa2+mongodb to build a blog system

Use koa2+mongodb to build a blog system

System style:

app.js

const path = require('path')
const config = require('./config')
const router = require('./router')
const Koa = require('koa')
const logger = require('koa-logger')
const bodyParser = require('koa-bodyparser')
const serve = require('koa-static')
const cors = require('koa-cors')
const convert = require('koa-convert')
const jwt = require('koa-jwt')
const errorHandler = require('./middlewares/errorhandler')
const log = require('./utils/log')
const Token = require('./utils/token')
const app = new Koa()

require('events').EventEmitter.defaultMaxListeners = 15

const mongoose = require('mongoose')
mongoose.connect(config.db.url)

const port = config.port || '8080'

const secret = Token.getSecret('public.pem')
const jwtOpts = {
    secret,
    isRevoked: Token.isRevoked, // token 
    tokenKey: 'token' // ctx.state.token
}

const jwtUnlessOpts = {
    path: [
        /^\/api\/register/,
       /^\/api\/login/,
       /^\/api\/getMenuList/,
       /^\/api\/getPage/,
       /^\/api\/getDetailPage/,
       /^\/js/,
       /^\/css/,
       /^\/fonts/,
       /.jpg$/
    ]
}

//middlewares
const middlewares = [
    convert(cors()),
    logger(),
    bodyParser(),
    serve(path.join(__dirname, config.publicPath)),
    serve(path.join(__dirname, config.uploadPath)),
    // token unless token 
    jwt(jwtOpts).unless(jwtUnlessOpts),
    errorHandler,
    router.routes(),
    router.allowedMethods()
]

middlewares.forEach(middleware => {
    if (!middleware) {
        return
    }
    app.use(middleware)
})

app.on('error', (err) => {
    log('cyan', err)
})

//koa static server
const server = app.listen(port, () => {
    log('magenta', 'The server is start on port ' + port)
})

//terminal ctrl+c to exit the server
process.on('SIGINT', () => {
    log('yellow', 'Stopping dev server')
    server.close(() => {
        process.exit(0)
    })
})
 

config.js

//server config
const config = {
    port: 3000, //server port
    db: {
        url: 'mongodb://localhost:27017/blog'
    },
    publicPath: '../static',
    uploadPath: '../uploads',
    secretKey: 'halapro'
}

module.exports = config
 

token.js

const fs = require('fs')
const path = require('path')
const jwt = require('jsonwebtoken')

module.exports = {
    getSecret (file) {
        return fs.readFileSync(path.join(__dirname, '../config/' + file))
    },
    // token
    generateToken (data) {
        // 
        let date = Math.floor(Date.now()/1000)
        const cert = this.getSecret('private.pem')
        const token = jwt.sign({data, exp: date + 3600 * 24}, cert, { algorithm: 'RS256' })
        return token
    },
    verifyToken (token) {
        if (token) {
            let res
            const cert = this.getSecret('public.pem')
            try {
                let result = jwt.verify(token, cert, { algorithm: 'RS256' }) || {}
                let { exp = 0 } = result, current = Math.floor(Date.now()/1000)
                if (current <= exp) {
                    res = result.data || {}
                }
            } catch (err) {
                console.log('verifyToken error:', err)
                throw err
            }
            return res
        }
    },
    isRevoked (ctx, decodedToken, token) {
        let currentTime = Math.floor(Date.now()/1000)
        let { exp = 0 } = decodedToken, current = Math.floor(Date.now()/1000)
        if (current <= exp) {
            return 0
        } else {
            return 1
        }
    }
}
 

errorHandler.js

/**
 * @description  
 * @author halapro.liu
 * @param {*} ctx
 * @param {*} next
 */
const errorHandler = async (ctx, next) => {
    try {
        await next()
    } catch (err) {
        console.log(`--------------------------------err---------------------------:`, err)
        ctx.status = err.statusCode || err.status || '500'
        ctx.body = {
            code: ctx.status,
            message: err.message
        }
    }
}

module.exports = errorHandler
 

For details, see github.com/halaproliu/...

Blog address gitbook brochure