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
- Navigate to the project directory
- Create project folders or create them manually
mkdir admin-server
Copy the code
- Open the admin server. –
cd admin-server
Copy the code
- Installation of koa
git init -y
npm install koa -S
Copy the code
- Create the main entry app.js
touch app.js
Copy the code
- 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
- Go to the mongodb installation directory and start Mongod
// My local pathcd /usr/local/mongodb/bin
suod mongod
Copy the code
- Create a database under admin-server
- Install the mongoose
npm install mongoose -S
Copy the code
- 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
- 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)
- Installation of koa – library of the router
npm install koa-router -S
Copy the code
- 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
- 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
- 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
- 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.
- Install KOA-JWT and JsonWebToken
npm install koa-jwt jsonwebtoken -S
Copy the code
- 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
- 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
- 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
- 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
- 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…