Koa – register login interface implementation notes
1, Construction project
- Write a basic app. Note: use must receive a function as middleware
//Import koa module
const Koa=require('koa');
//Create koa instance
const app=new Koa();
//Writing Middleware
app.use((ctx,next)=>{
ctx.body+='hello koa'
})
//Listening port
app.listen(3000,()=>{
console.log('server is running on http://localhost:3000')
})
- Project Optimization: use nodemon tool to automatically restart the service in package Add "dev" under the script of JSON file: "nodemon. / SRC / APP. JS", and then execute npm run dev to start the service.
- The function of dotenv module: change the variables in environment variables from Env is loaded into process env. Using dotenv, you can configure environment variables independently of the code.
//config.default.js
const dotenv=require('dotenv')
const path=require('path')
dotenv.config({path:path.resolve(__dirname,'../../.env')})
//console.log(process.env.APP_PORT)
//module.exports can use this object to share the members in the module for external use
//When the outside world uses the require() method to import a custom module, the result is module Objects referred to by exports
module.exports=process.env;
//app.js
//Import koa module
const Koa=require('koa');
//
const {APP_PORT}=require('./config/config.default')
//Create koa instance
const app=new Koa();
//Writing Middleware
app.use((ctx,next)=>{
ctx.body='hello koa'
})
//Listening port
app.listen(3000,()=>{
console.log(`server is running on http://localhost:${APP_PORT}`)
})
2, Add route
- Routing: call different processing functions according to different URL s
const Koa=require('koa');
const Router=require('koa-router')
//
const {APP_PORT}=require('./config/config.default')
const app=new Koa();
const indexRouter=new Router();
indexRouter.get('./',(ctx,next)=>{
ctx.body='hello index'
})
const userRouter=new Router();
userRouter.get('./user',(ctx,next)=>{
ctx.body='hello user'
})
//Writing Middleware
app.use(indexRouter.routes())
app.use(userRouter.routes())
//Listening port
app.listen(3000,()=>{
console.log(`server is running on http://localhost:${APP_PORT}`)
})
3, Koa body
- The basic function of KOA body middleware is to help parse the body in http, including json, forms, text, files, etc. Using koa body can replace koa body parser and KOA multer (KOA multer is a middleware for image upload).
//Import koa body
const KoaBody=require('koa-body')
app.use(KoaBody())//Note: be sure to register Koabody before routing!!!
- Note: be sure to register the KoaBody before routing
4, Directory structure optimization
- In actual projects, the code is often split to increase the readability of the code. Then import the split file as a custom module, which can reduce the coupling of the code. (custom module import: use the module exports object and the require method. The require import refers to the object pointed to by module exports)
- Split http service and app business
- Split the route and the controller file. Route: parse the URL and distribute it to the corresponding method of the controller; Controller: handles different services.
- Split the middleware processing and so on. When writing the code, you can reconstruct the repeated code according to the situation.
2. For example, index JS is the instance app file, config is the configuration file of environment variables, router is the routing file, controller is the routing control file, service is the database operation file, and main JS is the service startup file.
5, Use of rest client plug-in
- Use the rest client plug-in in vscode to send http requests for testing. Create in directory http file or The rest file writes the http request.
### test
POST http://localhost:3000/users/login
###test
POST http://localhost:3000/users/register
Content-Type: application/json
{
"user_name":"alice",
"password":"1234567"
}
6, Database operation
- Sequenize is a promise based node JS ORM database tool. Support Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server.
- ORM: object relational mapping. The data table maps a class, the data row (record) in the data table corresponds to an object, the fields in the data table correspond to the attributes of the object, and the operation of the data table corresponds to the methods of the object.
- Installation: you need to install serialize and database driver.
npm install sequelize
npm install mysql2
- Connect to the database: create a serialize instance and pass the connection parameters to the serialize constructor, or connect to a URI. (URI: uniform resource identifier, indicating every available resource on the web)
//Connect database
const {MYSQL_HOST,
MYSQL_PORT,
MYSQL_USER,
MYSQL_PWD,
MYSQL_DB}=require('../config/config.default')
const {Sequelize}=require('sequelize')//Deconstruct class
//Pass connection parameters
const sequelize=new Sequelize(MYSQL_DB,MYSQL_USER,MYSQL_PWD,{
host:MYSQL_HOST,
dialect:'mysql',
})
//Test whether the connection is successful
//Authjenticate () returns a promise object
sequelize.authenticate().then(()=>{
console.log('Database connection succeeded')
}).catch((err)=>{
console.log('Database connection failed',err)
})
//export
module.exports=sequelize;
- Model in serialize: the abstraction of the table in the database will specify the name of the table in the database, the columns and data types it has, and so on.
const {DataTypes}=require('sequelize')
const seq=require('../db/seq')
//Create and define models
const User=seq.define('zd_user',{
//id will be created automatically
user_name:{
type:DataTypes.STRING,
allowNull:false,
unique:true,
comment:'Unique user name'
},
password:{
type:DataTypes.CHAR,
allowNull:false,
comment:'password'
},
is_admin:{
type:DataTypes.BOOLEAN,
allowNull:false,
defaultValue:0,
comment:'Is it an administrator'
},
})
module.exports=User;
- The addition, deletion, modification, query and other operations of the database. Write down the next note separately.
7, Encryption
- Before saving the password to the database, you need to encrypt the password. Encryption using bcryptjs
- Salt encryption:
//encryption
const crpytPassword = async (ctx, next) => {
const { password } = ctx.request.body
//Salt is added and densified to form salt
const salt = bcryptjs.genSaltSync(1567)
//Encryption, hash saves the ciphertext
const hash = bcryptjs.hashSync(password, salt)
ctx.request.body.password = hash
console.log('Encrypted')
await next()
}
8, User authentication
- User authentication: maintain login status after login;
- Cookie: when the browser initiates an HTTP request, the server will set the cookie, that is, set cookie. There are two important attributes: name and value in the cookie. The server will fill in the value of the attribute in the cookie completely. After the cookie is sent to the browser, the browser will automatically save it, so that every request sent by the browser in the future will automatically attach the cookie. However, the user name and password are not safe in cookies and are easy to disclose.
- Session: the way to maintain a session between the browser and the server. The sessions of different websites and each user are set with time and unique ID (Session ID). The browser accessing the server is the beginning of the session. After successful login, the server will create a Session ID and session end time, and the server will send the Session ID and session end time to the browser, The browser will add the Session ID to the cookie and set the session end time as the validity period of the cookie. The next time you visit the browser, the cookie with Session ID will be sent to the server until the validity period of the cookie expires. The browser will delete the cookie by itself, the session will end and you need to log in again next time.
- JSON WEB TOKEN: jwt, after the user logs in the web page for the first time, the server will generate a token. The server does not need to save the token, but only needs to save the ciphertext of the token signature, and then send the token to the browser, which can be stored in the form of cookie or storage.
- JWT consists of three parts: header, payload and visa signature. The header part declares what algorithm is used to generate the signature. The payload part is some specific data. The contents of the header and payload parts will be encoded by Base64. The data and password will be calculated by a certain algorithm, and finally the signature information will be obtained. In this way, a complete JWT can be sent to the client.
- A cookie is a data carrier that follows every request from http to the server. The main difference between session and Token: the session is saved on the server side, and the browser uses the Session ID for authentication, while the token is saved in the browser, while the server only needs to save the password.