当前位置: 首页 > 后端技术 > Node.js

koa实现jwt认证

时间:2023-04-03 19:18:46 Node.js

关于Token认证机制,这里不做进一步说明。不清楚的可以看我的文章:Web开发中常用的认证机制GitHub地址:koa-jwt-sample所需的库bcrypt-用于加密密码koa-jwt-jwt中间件jsonwebtoken-用于生成令牌分发给浏览器,koa2之后的版本不再提供jsonwebtoken方法,需要单独安装。实现思路整个方案的实现过程和思路很清晰,大致分为以下几个步骤:自定义401拦截中间件,用于拦截不存在或者配置koa-jwt注册失败的token,实现登录运行项目.这个项目需要你已经安装并启动了Mongodb。有关mongodb配置,请参阅config/index.js。npmrunstart本项目提供了三个api/api/register/api/login/api/users,其中/api/register和/api/login为公共api,无需token即可访问。/users是私有api,需要传入正确的token才能访问。自定义401处理程序使用koa-jwt中间件后,如果没有token或者token不合法,中间件会给出相应的错误信息。如果没有自定义中间件,koa-jwt暴露的错误信息会直接返回给用户。//server/middlewares/errorHandle.jsexportdefaulterrorHandle=(ctx,next)=>{returnnext().catch((err)=>{if(err.status===401){ctx.status=401;ctx.body={error:err.originalError?err.originalError.message:err.message,};}else{throwerr;}});}然后使用中间件app.use(errorHandle)在index.js中使用koa-jwt在index.js中添加koa-jwt中间件。constsecret='jwt_secret'app.use(jwt({secret,}).unless({path:[/\/register/,/\/login/],}))其中secret是用于加密的密钥,不是限于字符串,也可以是文件。//https://github.com/koajs/jwt#token-verification-exceptionsvarpublicKey=fs.readFileSync('/path/to/public.pub');app.use(jwt({secret:publicKey}));unless()用于设置哪些API不需要通过token验证。也就是我们通常所说的publicapi,不需要登录就可以访问的api。本例中设置了/register和/login这两个API,不进行token校验。使用koa-jwt后,所有路由(除unless()设置的路由外)都会检查Header头中的token是否存在且有效。只有正确访问后才能正确。注册实现注册很简单,这里只是简单的将密码加密,并将信息存入数据库。在实际项目中,也需要对用户输入的字段进行校验。/***你可以注册*curl-XPOSThttp://localhost:3200/api/register-H'cache-control:no-cache'-H'content-type:application/x-www-form-urlencoded'-d'username=superman2&password=123456'*/asyncregister(ctx){const{body}=ctx.request;尝试{如果(!body.username||!body.password){ctx.status=400;ctx.body={错误:`需要一个带有用户名和密码的对象,但得到了:${body}`,}return;}body.password=awaitbcrypt.hash(body.password,5)letuser=awaitUser.find({username:body.username});如果(!user.length){constnewUser=newUser(body);user=awaitnewUser.save();ctx.status=200;ctx.body={message:'注册成功',user,}}else{ctx.status=406;ctx.body={message:'用户名已经存在',}}}catch(error){ctx.throw(500)}}登录实际用户输入用户名和密码登录,如果用户名和密码正确,使用jsonwebtoken.sign()生成token返回给客户端客户端将token存储在本地存储,并在每次HTTP请求中将token添加到HTTPHeaderAuthorization中:不记名令牌。然后后台每次都会验证token是否正确。只有token正确后,才能访问相应的资源。/**你可以使用*curl-XPOSThttp://localhost:3200/api/login/-H'cache-control:no-cache'-H'content-type:application/x-www-form-urlencoded'-d'username=superman2&password=123456'*/asynclogin(ctx){const{body}=ctx.requesttry{constuser=awaitUser.findOne({username:body.username});if(!user){ctx.status=401ctx.body={message:'用户名错误',}return;}//匹配的密码是否相等if(awaitbcrypt.compare(body.password,user.password)){ctx.status=200ctx.body={message:'登录成功',user:user.userInfo,//生成token返回给客户端token:jsonwebtoken.sign({data:user,//设置token过期时间exp:Math.floor(Date.now()/1000)+(60*60),//60秒*60分钟=1小时},secret),}}else{ctx.status=401ctx.body={message:'密码错误',}}}catch(error){ctx.throw(500)}}需要注意的是,在使用jsonwebtoken.sign()时,需要传入secret参数,这里的secret必须和之前设置的一样在jwt()中的秘密是一样的。更多关于jsonwebtoken的方法见:https://github.com/auth0/node-jsonwebtoken登录后,拿回返回的token,此时访问/api/users即可正确获取用户列表。curl-XGEThttp://localhost:3200/api/users-H'authorization:Bearertoken'-H'cache-control:no-cache'