Koa使用教程

一、KOA準備–搭建本地服務器

  • 1、首先創建一個目錄 koa-app ,用相關工具打開

    • 使用 npm init --yes 命令生成package.json 文件
    • 新建 app.js
  • 2、安裝 KOA

    • npm install koa koa-router -s
  • 3、在 app.js 中寫入:

      //引入模塊
      const Koa = require('koa');
      const Router = require('koa-router');
    
      //實例化 Koa、Router
      // 創建一個Koa對象表示web app本身:
      const app = new Koa();
      const router = new Router();
    
      //配置路由
      app.use(router.routes()).use(router.allowedMethods());
    
      //配置5000端口號
      const  port = process.env.PORT || 5000;
    
      //在5000端口監聽
      app.listen(port,()=>{
      console.log('server started on'+ port) ;
      });
    
      //使用路由跳轉
      router.get('/',async ctx=>{
      ctx.body = { msg:'Hello koa interfaces'};
      });
    
  • 4、在 package.json 文件 scripts 中配置:

      "scripts": {
      	"test": "echo \"Error: no test specified\" && exit 1",
      	"start": "node app.js",
      },
    
    • 安裝 nodemon ,使用 npm install -g nodemon 命令,並修改:

        "scripts": {
        	"test": "echo \"Error: no test specified\" && exit 1",
        	"start": "node app.js",
        	"nodemon": "nodemon app.js"
        },
      

二、KOA接口文檔–連接 Mongodb 數據庫

三、KOA接口文檔–創建測試接口和用戶模型

  • 1、新建文件夾 routers,在此下面新建文件夾 api ,再新建 user.js ,這個文件是關於用戶登錄等信息的接口文件

    • (1)在 user.js 中寫入

        //引入路由
        const  Router = require('koa-router');
        const  router = new Router();
      
        //test
        router.get('/test',async ctx=>{
        ctx.status = 200;
        ctx.body = {
        	 msg:'user works....'
        	}
        });
      
        module.exports = router.routes();
      
    • (2)在 app.js 中導入 user.js 並使用

        const users = require("./routers/api/users.js");
      
        //配置路由地址
        router.use('/api/users',users);
      
  • 2、配置用戶模型

    • (1)新建文件夾 models,再新建 User.js ,這個文件是關於用戶登錄等信息的模型

    • (2)在 User.js 中輸入

        const mongoose = require('mongoose');
        const Schema = mongoose.Schema;
      
        //實例化數據模板
        const UserSchema = new Schema({
        	name:{
        		type: String,
        		required: true
        	},
        	email:{
        		type: String,
        		required: true
        	},
        	password:{
        		type: String,
        		required: true
        	},
        	avatar:{
        		type:String
        	},
        	date:{
        		type: Date,
        		default: Date.now()
        	}
        });
      
        module.exports = User = mongoose.model("users",UserSchema);
      
    • (3)在 users.js 中導入 User.js

        const User = require('../../models/User.js');
      

四、KOA接口文檔–註冊接口和調試工具

  • 1、

    • 安裝 npm install koa-bodyparser -s,koa請求體解析中間件
    • 安裝 npm i bcryptjs ,對密碼進行加密
  • 2、在 app.js 中添加

      const bodyParser = require('koa-bodyparser');
      const bcrypt = require('bcryptjs');
    
      app.use(bodyParser());
    
  • 3、在 users.js 中修改

      router.post('/register',async ctx=>{
      //存儲到數據庫
      const findResult = await User.find({email: ctx.request.body.email});
      if(findResult.length > 0){
      	ctx.status = 500;
      	ctx.body = {
          	email: '郵箱已被佔用',
      	}
      }
      else {
      	const newUser = new User({
          	name: ctx.request.body.name,
          	email: ctx.request.body.email,
          	password:ctx.request.body.password
      	});
      	await bcrypt.genSalt(10, (err, salt)=> {
          	bcrypt.hash(newUser.password, salt, (err, 	hash)=> {
              	if(err) throw err;
              	newUser.password = hash
          	});
      	});
      	await newUser.save().then(user=>{
              	ctx.body = user;
          	}).catch(err=>{
              	console.log(err);
          	});
      	}
      });
    

五、KOA接口文檔–全球公認頭像的使用

  • 1、安裝 npm install gravatar

  • 2、在 users.js 文件中加入

      const gravatar = require('gravatar');
    

    const newUser = new User({}); 之前加入

      const avatar = gravatar.url(ctx.request.body.email, {s: '200', r: 'pg', d: 'mm'});
    

    注:gravatar.url 會返回一個頭像,如果在 全球公認頭像 中註冊過,則會返回一張圖片,如果沒有,則返回一張灰色沒有臉的圖片

六、KOA接口文檔–解決註冊接口加密問題

即解決往數據庫存儲時密碼依舊是明文的問題。將 users.js 中密碼部分抽離出來。
  • 1、在根目錄下新建 config 文件夾,在文件夾下新建 tools.js ,並在該文件中寫入

      const bcrypt = require('bcryptjs');
    
      const tools = {
      	enbcrypt(password){
      		var salt = bcrypt.genSaltSync(10);
     	 		var hash = bcrypt.hashSync(password,salt);
      		return hash;
      	}
      };
    
      module.exports = tools;
    

    並刪除 users.js 文件中的

      const bcrypt = require('bcryptjs');
    
      await bcrypt.genSalt(10, (err, salt)=> {
          	bcrypt.hash(newUser.password, salt, (err, 	hash)=> {
              	if(err) throw err;
              	newUser.password = hash
          	});
      	});
    

    將修改爲:

      const tools = require("../../config/tools.js");
      
      const newUser = new User({
          name: ctx.request.body.name,
          email: ctx.request.body.email,
          avatar:avatar,
          password:tools.enbcrypt(ctx.request.body.password)
      });
    

七、KOA接口文檔–登錄接口

  • 1、在 users.js 中添加

      //引入bcrypt
      const bcrypt = require('bcryptjs');
    
      /**
      *@route POST api/users/login
      * @desc 登錄接口地址 返回token
      * @access 接口是公開的
      */
    
      router.post('/login',async  ctx => {
      //查詢
      const  findResult = await  User.find({ email: ctx.request.body.email});
      //查詢到的數據庫的用戶
      const user = findResult[0];
      //輸入的密碼
      const  password = ctx.request.body.password;
      //判斷查沒查到
      if(findResult.length == 0){
      	ctx.status = 400;
      	ctx.body = { email : '用戶不存在'};
      }else {
      	//查驗後驗證密碼
      	var result = await bcrypt.compareSync(password, user.password);
      	if(result){
          	//返回token
    
          	ctx.status = 200;
          	ctx.body = { success: true };
      	}else {
          	ctx.status = 400;
          	ctx.body = { password: '密碼錯誤!'};
      		}
      	}
      });
    

八、KOA接口文檔–生成token

  • 1、安裝 jsonwebtoken

      npm install jsonwebtoken --save
    
  • 2、在 users.js 中使用 token

      //引入 jsonwebtoken
      const jwt = require('jsonwebtoken');
    
      //返回token
      const payload = { id:user.id, name: user.name, avatar: user.avatar};
      const token = jwt.sign(payload,'secret',{ expiresIn: 3600});
    

九、KOA接口文檔–passport驗證token

驗證郵箱密碼、賬號、token等是否正確

  • 1、安裝 koa-passport

      npm install koa-passport --save
    
  • 2、在 app.js 中寫入

      //引入 koa-passport
      const passport = require('koa-passport');
    
      app.use(passport.initialize());
      app.use(passport.session());
    
  • 3、在 config 文件夾下新建 passport.js 文件,並在 app.js 文件中回調

      //回調到 config 文件中 passport.js
      require('./config/passport.js')(passport);
    
  • 4、安裝 passport-jwt,用於使用 JSON Web TOKEN 進行身份驗證的 Passport 策略。

      npm install passport-jwt --save
    
  • 5、在 passport.js 文件中寫

      const JwtStrategy = require('passport-jwt').Strategy,
      	ExtractJwt = require('passport-jwt').ExtractJwt;
      const opts = {};
      opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
      opts.secretOrKey = 'secret';
      const mongoose = require("mongoose");
      const User = mongoose.model("users");
      module.exports = passport =>{
      	passport.use(new JwtStrategy(opts, async function(jwt_payload, done) {
      	const user = await User.findById(jwt_payload.id);
      	if(user){
          	return done(null,user);
      	}else {
          	return done(null,false);
      		}
      	}));
      };
    
  • 6、在 user.js 中添加

      router.get('/current',passport.authenticate('jwt', { session: false }),async ctx=>{
      	ctx.body = {
      		id: ctx.state.user.id,
      		name: ctx.state.user.name,
      		email: ctx.state.user.email,
      		avatar: ctx.state.user.avatar
      	}
      });
    

十、KOA接口文檔–使用 validator 驗證表單

  • 1、新建 validation 文件夾,新建 login.jsregister.js 文件,用於登錄和註冊的驗證

  • 2、安裝 npm i validator --save

  • 3、在 register.js 中寫入:

      const validator = require('validator');
      const isEmpty = require('./isEmpty.js');
      module.exports = function validateRegisterInput(data){
      	let errors = {};
    
      	if(!validator.isLength(data.name,{min:2,max:30})){
      		errors.name = "名字的長度不能小於兩位且不能超過30位";
      		}
      	return {
      		errors:errors,
      		isValid: isEmpty(errors)
      	}
      };
    
  • 4、在當前文件夾下新建 isEmpty.js , 並寫入

      const isEmpty = value => {
      	return value == undefined || value===null || (typeof value === "object") && Object.keys(value).length ===0 ||
      	(typeof value === 'string' && value.trim().length === 0);
      };
      module.exports = isEmpty;
    
  • 5、在 user.js 中引入

      //引入input驗證
      const validateRegisterInput = require('../../validation/register.js');
    

      router.post('/register',async ctx=>{
    
      }
    

    中添加

      const { errors,isvalid} = validateRegisterInput(ctx.request.body);
      //判斷是否通過
      if(!isvalid){
      	ctx.status = 400;
      	ctx.body = errors;
      	return ;
      }
    

十一、KOA接口文檔–驗證註冊和登錄的 input

  • 1、在 register.js 中更改

      data.name = !isEmpty(data.name) ? data.name : '';
      data.email = !isEmpty(data.email) ? data.email : '';
      data.password = !isEmpty(data.password) ? data.password : '';
      data.password2 = !isEmpty(data.password2) ? data.password2 : '';
      if(!validator.isLength(data.name,{min:2,max:30})){
      	errors.name = "名字的長度不能小於兩位且不能超過30位";
      }
      if(validator.isEmpty(data.name)){
          errors.name = '名字不能爲空';
      }
      if(!validator.isEmail(data.email)){
          errors.email = '郵箱不合法';
      }
      if(validator.isEmpty(data.email)){
          errors.email = '郵箱不能爲空';
      }
      if(validator.isEmpty(data.password)){
          errors.password = '密碼不能爲空';
      }
      if(!validator.isLength(data.password,{min: 6,max: 30})){
          errors.password = 'password的長度不能小於6位且不能超過30位';
      }
      if(validator.isEmpty(data.password2)){
          errors.password2 = 'password2不能爲空';
      }
      if(!validator.equals(data.password,data.password2)){
          errors.password2 = '兩次密碼不一致';
      }
    
  • 2、在 login.js 寫入

      const validator = require('validator');
      const isEmpty = require('./isEmpty.js');
      module.exports = function validateLoginInput(data){
      let errors = {};
    
      data.email = !isEmpty(data.email) ? data.email : '';
      data.password = !isEmpty(data.password) ? data.password : '';
    
      if(!validator.isEmail(data.email)){
          errors.email = '郵箱不合法';
      }
      if(validator.isEmpty(data.email)){
          errors.email = '郵箱不能爲空';
      }
      if(validator.isEmpty(data.password)){
          errors.password = '密碼不能爲空';
      }
      if(!validator.isLength(data.password,{min: 6,max: 30})){
          errors.password = 'password的長度不能小於6位且不能超過30位';
      }
    
      return {
          errors:errors,
          isValid: isEmpty(errors)
      	}
      };
    

    並在

      router.post('/login',async  ctx => {
      	
      	}
    

    加入

      const { errors,isValid} = validateLoginInput(ctx.request.body);
      //判斷是否通過
      if(!isValid){
          ctx.status = 400;
          ctx.body = errors;
          return;
      }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章