宝哥软件园

使用JWT的Node.js Koa2认证方法示例

编辑:宝哥软件园 来源:互联网 时间:2021-08-30

前言

在前端和后端分离的开发中,通过Restful API交换数据时,如果API没有受到保护,其他人很容易获取并调用这些API进行操作。那么服务器应该如何认证呢?

Json Web Token,简称JWT,定义了一种简洁且独立的方法,用于在通信双方之间以Json对象的形式安全地传输信息。JWT可以使用HMAC算法或RSA公钥对进行签名。

听起来好像是真的,那么如何进行认证呢?

首先,当用户登录时,他输入用户名和密码,然后请求服务器登录该界面。在服务器验证用户名和密码正确后,他生成一个令牌并将其返回给前端,前端存储该令牌并将其发送给服务器(在下面的请求中的请求头中)。服务器验证令牌是否有效,并返回正确的数据。

由于服务器使用Koa2框架进行开发,除了使用jsonwebtoken库外,还使用了koa-jwt中间件,为Koa封装jsonwebtoken,使用起来更加方便。让我们看看它是如何使用的。

生成令牌

这里注册了/login路由,用于用户登录时获取令牌。

const router=require(' KOA-router ')();const jwt=require(' jsonwebtoken ');const userModel=require('./models/UserMoDEL . js ');router.post('/login ',async(CTX)={ const data=CTX . request . body;if(!data.name ||!data . password){ return CTX . body={ code : ' 00002 ',data: null,msg: '参数非法' } } const result=wait user model . find one({ name 3360 data . name,password 3360 data . password })if(result==null){ const token=jwt . sign({ name : result . name,_id: result。_id }、' my_token '、{ expire resi : ' 2h ' });返回CTX。body={code:' 00001 ',data:token,msg: '登录成功' }} else {returnctx。body={code3360' 00002 ',data: null,msg: '错误的用户名或密码' } } module.exports=router验证用户名和密码正确后,调用jsonwebtoken的sign()方法生成token,并接收三个参数。第一个是有效载荷,用于编码后存储在令牌中的数据,以及验证令牌后可以获得的数据;第二个是钥匙,它是自己定义的。验证时,需要相同的密钥进行解码;第三个是选项,可以设置令牌的到期时间。

获取令牌

接下来,前端获取令牌。这里,axios用于在vue.js中进行请求,请求成功后,获取令牌并保存在localStorage中。登录成功后,保存当前时间。除了判断令牌是否存在,还可以简单判断当前令牌是否过期。如果过期,请跳过登录页面

submit(){ axios.post('/login ',{ name: this.username,password: this.password })。然后(RES={ if(RES . code==' 000001 '){ local storage . setitem(' token ',RES . data);local storage . setitem(' token _ exp ',新日期()。getTime());这个。$ router . push('/');} else { alert(RES . msg);}})}然后在请求服务器API的时候,把token带入请求头,发送到服务器进行验证。每次发出请求时,在localStorage中获取令牌都非常麻烦。这里使用了axios的请求拦截器,令牌被获取并放入每个请求的头部。

axios . interceptors . request . use(config={ const token=local storage . getitem(' token ');公共['授权']='承载'令牌;返回配置;})验证令牌

通过koa-jwt中间件进行了验证,其使用也非常简单

const KOA=require(' KOA ');const koajwt=require(' KOA-jwt ');const app=new KOA();//错误处理app。使用((CTX,下一个)={返回下一个()。catch ((err)={if (err。status==401) {CTX。状态=401;ctx.body='受保护的资源,使用授权头获取访问权限 n ';} else { throw err} })})app . use(koajwt({ secret : ' my _ token ' })。除非({ path :[//user /log in/]});通过app.use调用中间件,并传入密钥{secret: 'my_token'}。除非可以指定哪些URL不需要令牌验证。令牌认证失败会抛出错误401,所以需要在app.use(koajwt())之前添加错误处理,否则不会执行。

如果在请求时没有令牌或者令牌过期,将返回401。

koa-jwt分析

我们使用了jsonwebtoken的sign()方法来生成token,那么koa-jwt做了什么来帮助我们验证token呢?

resolvers/auth-header . jsmodule . exports=function resolveAuthorizationHeader(CTX,opts) { if(!ctx.header ||!CTX . header . authorization){ return;} const parts=CTX . header . authorization . split(');if(parts . length===2){ const scheme=parts[0];const凭据=parts[1];if (/^Bearer$/i.test(scheme)) {返回凭据;} } if(!opts . pass through){ CTX . throw(401,'错误的授权头格式。格式为Authorization:承载令牌’);}};在auth-header.js中,判断请求头是否携带授权,如果携带,则将令牌与授权分开。如果没有授权,则表示客户端没有向服务器发送令牌,然后抛出错误状态401。

verify.js

const jwt=require(' jsonwebtoken ');module.exports=(.args)={返回新的Promise((解析,拒绝)={ jwt.verify(.args,(错误,解码)={错误?拒绝(错误):解析(已解码);});});};在verify.js中,使用jsonwebtoken提供的verify()方法来验证并返回结果。jsonwebtoken的sign()方法用于生成令牌,而verify()方法用于验证和解析令牌。如果令牌无效,将在此方法中进行验证。

index.js

const decodedToken=wait verify(token,secret,opts);if(isRevoked){ const token revered=wait isRevoked(CTX,decodedToken,token);if(令牌已吊销){引发新错误('令牌已吊销');} } CTX . state[key]=decodedToken;//这里key=' user ' if(token key){ CTX . state[token key]=token;}在index.js中,调用verify.js的方法验证并解析token,得到数据{name:result.name,_id:result。_ id}上面签名,并分配给ctx.state.user,在控制器中,可以直接通过ctx.state.user获取名称和_ id。

安全

如果JWT的加密密钥被泄露,你可以根据密钥生成令牌,随意请求API。因此,密钥一定不能存在于前端代码中,否则很容易被发现。在HTTP请求中,token放在头中,中间可以通过包抓取工具轻松抓取头中的数据。即使HTTPS能被捕获,也是加密传输的,所以拿不到令牌,会相对安全。摘要

这是jwt的基本流程,可能并不完美,但对于大多数登录来说已经足够了。

以上代码可能不够具体。这里可以参考一下Koa mongoose vue.js实现的一个例子jwt-demo。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

更多资讯
游戏推荐
更多+