上一节回顾使用Element、scss、axios路由定义和跳转登录&注册客户端逻辑工作内容crypto-js加密服务器端参数校验准备npmi-Scrypto-js//先切换到/client目录下npminstall-Skoa-bouncer//先切换到/server目录下更新逻辑前端-endencryption是明文的,这里借助crypto-js对密码进行了加密。//更新:client/src/views/login/index.vue...从'crypto-js/md5'导入md5...constres=awaithttp.post('/users?action=login',{account,密码:md5(password).toString()})...constres=awaithttp.post('/users?action=register',{账号,密码:md5(password).toString()})...请求登录和注册接口参数时加密。测试结果动态测试结果后端验证在前端表单提交中,有验证逻辑:但是通过Postman/其他方式请求接口时,不会进行这些验证,所以需要后端验证。如果不使用库验证,不使用第三方包,可以自定义一个中间件(这里是特例)//新建文件:server/validation/user.jsconstvalidate=(ctx,next)=>{const{账号,密码}=ctx.request.body;//account:[//{required:true,message:'请输入帐号',trigger:'blur'},//{min:5,message:'长度必须至少为5个字符',trigger:'blur'}//],//password:[//{required:true,message:'Pleaseenteryourpassword',trigger:'blur'},//{min:3,message:'length至少3个字符',trigger:'blur'}//]if(!account||!password){ctx.body={code:'403',data:null,msg:'账号/密码不能为空'}return;}if(account.trim().length<5){ctx.body={code:'403',data:null,msg:'Accountlengthmustbeatleast5characters'}return;}next()}module.exports={validate}//更新文件:server/router/users.js...const{validate}=require('../validation/user');//Add...{path:'/',method:'POST',handle:async(ctx)=>{...},middlewares:[validate//New]},...//更新文件:服务器/实用程序/router.jsfunctionregister(routes){routes.forEach((route,idx)=>{const{path,method,middlewares=[],handle}=route;//添加中间件this[method.toLowerCase()](path,...middlewares,async(ctx,next)=>{awaithandle(ctx);})})}module.exports={register,}使用koa-bouncerchecksum和'nolibrarycheck'二选一,使用该方法时,注意还原'withoutlibraryverification'的代码//更新文件:server/app.js...constbouncer=require('koa-bouncer');//添加新的constroutes=require('./router');constapp=newkoa();app.use(cors());app.use(bouncer.middleware());//添加//中间件错误处理app.use(function(ctx,next){//添加console.log(err)if(err.name==='ValidationError'){//如果验证失败,根据error类型处理ctx.body={code:'403',data:null,msg:err.message}}});});...如果bouncer验证失败,报错会抛出,根据错误类型做相应处理//更新文件:server/router/users.js...constvalidate=async(ctx,next)=>{ctx.validateBody('account').required('Accountisrequired').isString('Accountmustbeastring').trim().tap(x=>x.length).gte(4,'帐号长度必须至少为5characters')ctx.validateBody('password').required('Thepasswordisrequired').isString('Thepasswordmustbeastring').trim()awaitnext();//这个必须是async/await的形式,否则像动态图一样,没有返回值。}...{路径:'/',方法:'POST',句柄:异步(ctx)=>{const{action}=ctx.query;switch(action){case'register':awaitregister(ctx);休息;案例'登录':等待登录(ctx);休息;默认值:等待列表(ctx);}},middlewares:[validate//new]},...//更新文件:server/utils/router.jsfunctionregister(routes){routes.forEach((route,idx)=>{const{path,method,middlewares=[],handle}=route;//添加中间件this[method.toLowerCase()](path,...middlewares,async(ctx,next)=>{awaithandle(ctx);})})}module.exports={register,}测试结果动态测试结果参考文档crypto-jskoa-bouncer