start

Node and Mongodb installation

There are many tutorials for installing Node and mongodb on the web, so you can follow them step by step.

Build the project

  1. Navigate to the project directory
  2. Create project folders or create them manually
mkdir admin-server
Copy the code
  1. Open the admin server. –
cd admin-server
Copy the code
  1. Installation of koa
git init -y
npm install koa -S
Copy the code
  1. Create the main entry app.js
touch app.js
Copy the code
  1. Creating the initial service
// introduce koa const koa = require('koa') const app = new Koa() // Start service // listen to app.listen(3000, () => {console.log()'[Koa] Server is starting at port 3000! ')})Copy the code

Connect code to mongodb

You can query the basic operations of mongodb in the mongodb tutorial

The mongodb visualization tool Robo 3T is recommended

Before connecting mondoDB, start the mongodb service

  1. Go to the mongodb installation directory and start Mongod
// My local pathcd /usr/local/mongodb/bin
suod mongod
Copy the code
  1. Create a database under admin-server
  2. Install the mongoose
npm install mongoose -S
Copy the code
  1. Create index.js in database
// /admin/database/index.js // 1. Const mongoose = require('mongoose'// 2. Database address const DB_ADDRESS ='mongodb://localhost:27017/admin-server'// connect to mongoose. Connect (DB_ADDRESS, {useNewUrlParser:true}, err => {
  if (err) {
    console.log('[Mongoose] database connect failed! ')}else {
    console.log('[Mongoose] database connect success! ')
  }
})

module.exports = mongoose
Copy the code
  1. Modify the configuration of the import file app.js
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')

const router = require('./api')
const mongoose = require('./database')

app.listen(3000, () => {
  console.log(`[Koa]Server is starting at port 3000`)
})
Copy the code

At this point, the initial work of the project has been completed!

The development of

Routing (Interface development)

  1. Installation of koa – library of the router
npm install koa-router -S
Copy the code
  1. Create an API folder under the root of your project, and create the Modules folder and the route exit module index.js under the file

app.js

// app.js
const Koa = require('koa')
const bodyParser = require('koa-bodyparser'// import route const router = require('./api')
const mongoose = require('./database') const app = new Koa() app.use(bodyParser()) // Mount route app.use(router.routes()).use(router.allowedMethods()) app.listen(3000, () => { console.log(`[Koa]Server is starting at port 3000`) })Copy the code
  1. Write route exit file/API /index.js
// import the component const Router = require('koa-router'// import router module const userRouter = require('./modules/user') // Instantiate const router = new router () // Register router.'/user', userRouter routes (), userRouter allowedMethods ()) / / export routing module. Exports = the routerCopy the code
  1. Write the specific route/API /modules/user.js/API /modules/todo.js
const Router = require('koa-router'Const router = new router () // Register get method router.get()'/login', async (ctx, next) => {
  ctx.body = {
    code: 1,
    msg: 'success'// Register the post method router.post('/register', async (ctx, next) => {
  ctx.body = {
    code: 1,
    msg: 'success'
  }
})

module.exports = router

Copy the code
const Router = require('koa-router')
const mongoose = require('mongoose')
const Todo = require('.. /.. /database/schema/Todo')

const router = new Router()

router.post('/save', async (ctx, next) => {
  const req = ctx.request.body
  const todoItem = {
    userId: req.userId,
    content: req.content,
    status: req.status
  }
  const todo = new Todo(todoItem)
  const result = todo.save()
  
  if (result) {
    ctx.body = {
      code: 1,
      msg: 'success'}}else {
    ctx.body = {
      code: 0,
      msg: 'failed'
    }
  }
})

router.post('/update', async (ctx, next) => {
  const req = ctx.request.body
  const res = await Todo.updateOne({
    _id: mongoose.Types.ObjectId(req._id)
  }, {
    status: req.status === '0'? 1:0})if (res.nModified === 1) {
    ctx.body = {
      code: 1,
      msg: 'success'}}else {
    ctx.body = {
      code: 0,
      msg: 'failed'
    }
  }
})

module.exports = router
Copy the code
  1. Modify/API/index. Js
const Router = require('koa-router')

const userRouter = require('./modules/user'// todo const todoRouter = require('./modules/todo')

const router = new Router()

router.use('/user', userRouter routes (), userRouter allowedMethods ()) / / mount todo the router. Use ('/todo', todoRouter.routes(), todoRouter.allowedMethods()) 

module.exports = router
Copy the code

The KOA-BodyParser middleware does not support form-data, so if the post type is form-date, the value obtained using CTx.request. body is null, and x-www-form-urlencoded posts can be sent Parameter, or use koA-body middleware instead

JWT authentication

JWT, short for JSON Web Token, is the most popular cross-domain authentication solution at present. The basic process is that after successful login through the interface, the Token returned by the background is saved locally, and the Token is put into the request header Authorization when requesting other authentication interfaces In the field, the background checks whether the token has expired. If the token has expired, the background returns 401 or other operation prompt.

  1. Install KOA-JWT and JsonWebToken
npm install koa-jwt jsonwebtoken -S
Copy the code
  1. The project root directory is created in /utils/token.js
// utils/token.js // utils/token.js //'jsonwebtoken') // key const JWT_SECRET ='token'CreateToken = (data, expiresIn =); // The logon request generates the token method exports.createToken = (data, expiresIn =) by getting the user username and _id'1h') => {
  const { username, _id } = data
  letOpt = {username, _id} const exp = {expiresIn}returnJWT.sign(opt, JWT_SECRET, Exp)} // User requests to other authentication interfaces are parse headers, return authorization // request header authorization carries token concatenation in the format of 'Bearer'${token}ParseHader = CTX => {// If the token is exported, the authorization field must be handled.if(! ctx || ! ctx.request || ! ctx.request.header || ! ctx.request.header.authorization)return null
  returnCTX. Request. The header. The authorization} / / parsing token exports. DecodeToken = token = > {return JWT.decode(token)
}

exports.JWT_SECRET = JWT_SECRET
Copy the code
  1. Modifying a Login Interface
// /api/modules/user.js
const Router = require('koa-router'Const {createToken} = require(const {createToken} = require('.. /.. /utils/token')
router.get('/login', async (ctx, next) => {
  const req = ctx.request.body
  const user = await User.findOne({
    username: req.username,
    password: req.password
  })
  if (user) {
    let token = createToken(user)

    ctx.body = {
      code: 1,
      msg: 'Login successful',
      data: {
        token
      }
    }
  } else {
    ctx.body = {
      code: 0,
      msg: 'Incorrect username or password'}}})Copy the code

After completing the above steps, restart the service and test the login interface to find that we have obtained the required token

  1. Modify /app.js to block tokens uniformly and set routes that do not need to be blocked
const Koa = require('koa')
const bodyParser = require('koa-bodyparser'// const JWT = require('koa-jwt'Const {JWT_SECRET} = require('./utils/token')

const router = require('./api')
const mongoose = require('./database')

const app = new Koa()

app.use(bodyParser())

// jwt 拦截错误处理,被 jwt 拦截后会返回 401
app.use((ctx, next) => {
  return next().catch(err => {
    if (err.status === 401) {
      ctx.status = 401
      ctx.body = {
        code: 401,
        mag: 'No permissions currently'}}else{throw err}})}) app.use(JWT ({secret: JWT_SECRET}).unless({path: [ /^\/user\/login/, /^\/user\/register/, ] }) ) app.use(router.routes()) .use(router.allowedMethods()) app.listen(3000, () => { console.log(`[Koa]Server is starting at port 3000`) })Copy the code

The JWT middleware needs to be mounted before the route is mounted

  1. Authentication token

Add token validation middleware at /utils/token.js

exports.verify = () => {
  return async (ctx, next) => {
    let token = this.parseHader(ctx)
    try {
      let decode = JWT.verify(token, JWT_SECRET)
      let { _id } = decode
      if(_id) {ctx.status = 200 await next()}} catch (err) {// Error tolerant filter the route set in KOa-jwt unlessif (token == null) {
        await next()
      } else {
        ctx.body = {
          code: 401,
          msg: 'Token verification error'
        }
      }
    }
  }
}
Copy the code

Set status = 200 to pass validation, otherwise correct data will not be returned

Introduce token validation middleware in /app.js and use it

const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const jwt = require('koa-jwt')
const { JWT_SECRET, verify } = require('./utils/token')

const router = require('./api')
const mongoose = require('./database')

const app = new Koa()

app.use(bodyParser())

app.use((ctx, next) => {
  return next().catch(err => {
    console.log(err)
    if (err.status === 401) {
      ctx.status = 401
      ctx.body = {
        code: 401,
        mag: 'No permissions currently'}}else {
      throw err
    }
  })
})

app.use(
  jwt({ secret: JWT_SECRET})
    .unless({
      path: [
        /^\/user\/login/,
        /^\/user\/register/,
      ]
    })
)

app.use(verify())

app.use(router.routes())
  .use(router.allowedMethods())
  
  
  

app.listen(3000, () => {
  console.log(`[Koa]Server is starting at port 3000`)
})
Copy the code
  1. Using Token Information

Modify/API /modules/todo.js to add interface to get user todo list

router.post('/list', async (ctx, next) => {
  const token = parseHader(ctx)
  const tokenDecoded = decodeToken(token)
  const { _id } = tokenDecoded
  const todoList = await Todo.find({
    userId: _id
  })
  if (todoList) {
    ctx.body = {
      code: 1,
      data: todoList,
      msg: 'success'}}else {
    ctx.body = {
      code: 0,
      msg: 'failure'}}})Copy the code
// Test interface result {"code": 1,
    "data": [{"content": "Test todo - 1"."_id": "5d43b0670f4dc43336b3ea38"."userId": "5d43ac2f854fb42f399e142e"."status": 0."createdAt": "The 2019-08-02 T03: they. 305 z"."updatedAt": "The 2019-08-02 T03: they. 305 z"."__v": 0}, {"content": "Test todo - 2"."_id": "5d43b11d6685db340dc882d1"."userId": "5d43ac2f854fb42f399e142e"."status": 0."createdAt": "The 2019-08-02 T03: pleased. 865 z"."updatedAt": "The 2019-08-02 T03: pleased. 865 z"."__v": 0}],"msg": "Success"
}
Copy the code

To be continued…