版权声明转载请告知并注明出处作者:唐金剑网络昵称:玉言掘金知乎思想专栏:优雅前端一、基于Token身份的前置知识验证Koajs中文DocumentationKoaFrameworkTutorial2.环境MicrosoftVisualStudio2017集成开发环境Node.jsv8.9.4Javascript运行环境3.开始逐步完善1.创建一个基本的静态资源服务器和基础设施下面是基础代码实现staticserver,token校验异常时的处理。接下来我们会在这个基础代码下逐步增加注册、登录、信息功能。constpath=require('路径');//用于处理目录路径constKoa=require('koa');//Web开发框架constserve=require('koa-static');//静态资源处理constroute=require('koa-route');//路由中间件constjwt=require('jsonwebtoken');//用于发行和解析`token`constjwtKoa=require('koa-jwt');//用于路由权限控制constkoaBody=require('koa-body');//用于将查询字符串解析为`ctx.request.query`constapp=newKoa();constwebsite={scheme:'http',host:'localhost',port:1337,join:function(){return`${this.scheme}://${this.host}:${this.port}`}}/*jwtkey*/constsecret='secret';/*token验证异常时的处理,如token过期、token错误*/app.use((ctx,next)=>{returnnext().catch((err)=>{if(err.status===401){ctx.status=401;ctx.body={ok:false,msg:err.originalError?err.originalError.message:err.message}}else{抛出错误;}});});/*查询字符串解析为`ctx.request.query`*/app.use(koaBody());/*路由权限控制*///TODO.../*POST/api/register注册*///todo.../*GET/api/loginlogin*///todo.../*GET/api/infoinfo*///todo.../*静态资源处理*/app.use(serve(path.join(__dirname,'static')));/*监听服务器端口*/app.listen(website.port,()=>{console.log(`${website.join()}服务器已启动!`);});接下来我们添加实现代码2,注册、登录、信息注解下的路由权限控制接口需要鉴权。/*路由权限控制*/app.use(jwtKoa({secret:secret}).unless({//设置登录注册接口,无需认证即可访问path:[/^\/api\/login/,/^\/api\/register/,/^((?!\/api).)*$///设置除私有接口外的其他资源,无需认证即可访问]}));3.注册/*POST/api/registerregister*/app.use(route.post('/api/register',async(ctx,next)=>{constbody=ctx.request.body;/**body={*user:'Yuyan',*password:'123456'*}*///判断body.user和body.password的格式是否正确//To-do...//判断用户是否已经注册//待办...//保存到数据库中的新用户//待办事项...//是否注册成功let是否注册成功=true;if(是否注册successful){//返回一个注册成功的JSON数据给前端returnctx.body={ok:true,msg:'注册成功',token:getToken({user:body.user,password:body.password})}}else{//返回一个注册失败的JSON数据给前端returnctx.body={ok:false,msg:'Registrationfailed'}}}));/*得到一个周期为4的token小时*/functiongetToken(payload={}){returnjwt.sign(payload,secret,{expiresIn:'4h'});}3.登录/*GET/api/login登录*/app.use(route.get('/api/login',async(ctx,next)=>{constquery=ctx.request.query;/**query={*user:'Yuyan',*password:'123456'*}*///判断query.user和query.password格式是否正确//待办事项...//判断是否有已注册//待办事项...//判断姓名和学号是否正确//待办事项...returnctx.body={ok:true,msg:'登录成功',token:getToken({用户:query.user,密码:query.password})}}));前端获取到token后,可以保存在任意本地存储中4.Information/*GET/api/infoinformation*/app.use(route.get('/api/info',async(ctx,next)=>{//访问前端时,会附加一个token到请求头payload=getJWTPayload(ctx.headers.authorization)/**payload={*user:"Yuyan",*iat:1524042454,*exp:1524056854*}*///根据数据库查询用户信息topayload.user//待办事项...constinfo={name:'Yuyan',age:10,sex:'男'}letgetinformationsuccessfully=true;if(getinformationsuccessfully){returnctx.body={ok:true,msg:'获取信息成功',data:info}}else{returnctx.body={ok:false,msg:'获取信息失败'}}}));/*获取JWTpayloadpartthroughtoken*/functiongetJWTPayload(token){//验证并解析JWTreturnjwt.verify(token.split('')[1],secret);}访问需要认证的接口时,需要将Authorization:Bearer[token]附加到请求标头字段。
