• 售前

  • 售后

热门帖子
入门百科

Node使用koa2实现一个简单JWT鉴权的方法

[复制链接]
我心永恒760 显示全部楼层 发表于 2021-10-25 19:42:44 |阅读模式 打印 上一主题 下一主题
JWT 简介

什么是 JWT

全称
  1. JSON Web Token
复制代码
, 是现在最盛行的跨域认证解决方案。基本的实现是服务端认证后,天生一个
  1. JSON
复制代码
对象,发回给用户。用户与服务端通讯的时候,都要发回这个
  1. JSON
复制代码
对象。
  1. JSON
复制代码
类似如下:
  1. {
  2. "姓名": "张三",
  3. "角色": "管理员",
  4. "到期时间": "2018年7月1日0点0分"
  5. }
复制代码
为什么必要 JWT

先看下一样平常的认证流程,基于
  1. session_id
复制代码
  1. Cookie
复制代码
实现
1、用户向服务器发送用户名和密码。
2、服务器验证通过后,在当前对话(
  1. session
复制代码
)内里保存相关数据,好比用户角色、登录时间等等。
3、服务器向用户返回一个
  1. session_id
复制代码
,写入用户的
  1. Cookie
复制代码

4、用户随后的每一次哀求,都会通过
  1. Cookie
复制代码
,将
  1. session_id
复制代码
传回服务器。
5、服务器收到
  1. session_id
复制代码
,找到前期保存的数据,由此得知用户的身份。
但是这里有一个大的问题, 假如是服务器集群,则要求 session 数据共享,每台服务器都可以或许读取 session 。这个实现资本是比较大的。
  1. JWT
复制代码
转换了思绪,将
  1. JSON
复制代码
数据返回给前端的,前端再次哀求时候将数据发送到后端,后端进行验证。也就是服务器是无状态的,所以更加轻易拓展。
JWT 的数据结构
  1. JWT
复制代码
的三个部分依次如下:
  1. Header
复制代码
(头部),类似如下
  1. {
  2. "alg": "HS256",
  3. "typ": "JWT"
  4. }
复制代码
  1. alg
复制代码
属性体现署名的算法(
  1. algorithm
复制代码
),默认是
  1. HMAC SHA256
复制代码
(写成
  1. HS256
复制代码
)。
  1. typ
复制代码
属性体现这个令牌(
  1. token
复制代码
)的范例(
  1. type
复制代码
),
  1. JWT
复制代码
令牌同一写为
  1. JWT
复制代码
  1. Payload
复制代码
(负载)。也是一个
  1. JSON
复制代码
,用来存放现实必要转达的数据。
  1. JWT
复制代码
规定了 7 个官方字段。如下所示
      
  • iss (issuer):签发人  
  • exp (expiration time):逾期时间  
  • sub (subject):主题  
  • aud (audience):受众  
  • nbf (Not Before):生效时间  
  • iat (Issued At):签发时间  
  • jti (JWT ID):编号
固然也可以自定义私有字段。 但是要注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
  1. Signature
复制代码
(署名)。
  1. Signature
复制代码
部分是对前两部分的署名,防止数据窜改。起首,必要指定一个密钥(
  1. secret
复制代码
)。这个密钥只有服务器才知道,不能走漏给用户。然后,使用
  1. Header
复制代码
内里指定的署名算法(默认是
  1. HMAC SHA256
复制代码
),按照下面的公式产生署名。
  1. HMACSHA256(
  2. base64UrlEncode(header) + "." +
  3. base64UrlEncode(payload),
  4. secret)
复制代码
算出署名以后,把
  1. Header
复制代码
  1. Payload
复制代码
  1. Signature
复制代码
三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。如下所示

JWT 的安全
      
    1. JWT
    复制代码
    默认是不加密,但也是可以加密的。
    1. JWT
    复制代码
    不加密的情况下,不能将秘密数据写入
    1. JWT
    复制代码

    1. JWT
    复制代码
    自己包含了认证信息,一旦走漏,任何人都可以得到该令牌的全部权限。为了减少盗用,
    1. JWT
    复制代码
    的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证  
  • 为了减少盗用,
    1. JWT
    复制代码
    不应该使用
    1. HTTP
    复制代码
    协议明码传输,要使用
    1. HTTPS
    复制代码
    协议传输
Node 简单demo—— Koa JWT 的实现

说完理论知识,我们来看下怎样实现
  1. JWT
复制代码
,大致的流程如下:

起首,用户登录后服务端根据用户信息天生并返回
  1. token
复制代码
给到客户端,前端在下次哀求中把
  1. token
复制代码
带给服务器,服务器验证有效后,返回数据。无效的话,返回
  1. 401
复制代码
状态码
这里我们用
  1. Node
复制代码
实现,主要用到的两个库有
jsonwebtoken ,可以天生
  1. token
复制代码
,校验等
koa-jwt 中心件 对
  1. jsonwebtoken
复制代码
进一步的封装,主要用来校验
  1. token
复制代码
快速搭建一个 koa 项目

发现官方现在没有一个快速搭建
  1. koa
复制代码
项目标方式,像
  1. Vue-cli
复制代码
一样。(大概是搭建一个
  1. koa
复制代码
项目资本也很低)。但懒人的我,还是找到了一个工具 ——koa-generator ,使用也相对简单,如下
安装
  1. npm install -g koa-generator
复制代码
  1. koa2 my-project
复制代码
新建一个叫做
  1. my-project
复制代码
  1. koa2
复制代码
项目
  1. cd my-project
复制代码
  1. npm install
复制代码
启动项目
  1. npm start
复制代码
打开
  1. localhost:3000
复制代码
天生 Token

为了演示方便,我这里直接定义了变量
  1. userList
复制代码
存储用户的信息,真实应该是存放在数据库中的。
  1. const crypto = require("crypto"),
  2. jwt = require("jsonwebtoken");
  3. // TODO:使用数据库
  4. // 这里应该是用数据库存储,这里只是演示用
  5. let userList = [];
  6. class UserController {
  7. // 用户登录
  8. static async login(ctx) {
  9.   const data = ctx.request.body;
  10.   if (!data.name || !data.password) {
  11.    return ctx.body = {
  12.     code: "000002",
  13.     message: "参数不合法"
  14.    }
  15.   }
  16.   const result = userList.find(item => item.name === data.name && item.password === crypto.createHash('md5').update(data.password).digest('hex'))
  17.   if (result) {
  18.    const token = jwt.sign(
  19.     {
  20.      name: result.name
  21.     },
  22.     "Gopal_token", // secret
  23.     { expiresIn: 60 * 60 } // 60 * 60 s
  24.    );
  25.    return ctx.body = {
  26.     code: "0",
  27.     message: "登录成功",
  28.     data: {
  29.      token
  30.     }
  31.    };
  32.   } else {
  33.    return ctx.body = {
  34.     code: "000002",
  35.     message: "用户名或密码错误"
  36.    };
  37.   }
  38. }
  39. }
  40. module.exports = UserController;
复制代码
通过
  1. jsonwebtoken
复制代码
  1. sign
复制代码
方法天生一个
  1. token
复制代码
。该方法第一个参数指的是
  1. Payload
复制代码
(负载),用于编码后存储在
  1. token
复制代码
中的数据,也是校验
  1. token
复制代码
后可以拿到的数据。第二个是秘钥,服务端特有, 注意校验的时候要类似才气解码,而且是保密的 ,一样平常而言,最好是定公共的变量,这里只是演示方便,直接写死。第三个参数是
  1. option
复制代码
,可以定义
  1. token
复制代码
逾期时间
客户端获取 token

前端登录获取到
  1. token
复制代码
后可以存储到
  1. cookie
复制代码
中也可以存放在
  1. localStorage
复制代码
中。这里我直接存到了
  1. localStorage
复制代码
  1. login() {
  2. this.$axios
  3.   .post("/api/login", {
  4.    ...this.ruleForm,
  5.   })
  6.   .then(res => {
  7.    if (res.code === "0") {
  8.     this.$message.success('登录成功');
  9.     localStorage.setItem("token", res.data.token);
  10.     this.$router.push("/");
  11.    } else {
  12.     this.$message(res.message);
  13.    }
  14.   });
  15. }
复制代码
封装
  1. axios
复制代码
的拦截器,每次哀求的时候把
  1. token
复制代码
带在哀求头发送给服务器进行验证。这里如果之前放在
  1. Cookie
复制代码
中,可以让它自动发送,但是这样不能跨域。所以保举做法是放在 HTTP 哀求头
  1. Authorization
复制代码
中,注意这里的
  1. Authorization
复制代码
的设置,前面要加上
  1. Bearer
复制代码
。详情可以见 Bearer Authentication
  1. // axios 请求拦截器处理请求数据
  2. axios.interceptors.request.use(config => {
  3. const token = localStorage.getItem('token');
  4. config.headers.common['Authorization'] = 'Bearer ' + token; // 留意这里的 Authorization
  5. return config;
  6. })
复制代码
校验 token

使用
  1. koa-jwt
复制代码
中心件进行验证,方式比较简单,如下所示
  1. // 错误处理
  2. app.use((ctx, next) => {
  3. return next().catch((err) => {
  4.    if(err.status === 401){
  5.      ctx.status = 401;
  6.     ctx.body = 'Protected resource, use Authorization header to get access\n';
  7.    }else{
  8.      throw err;
  9.    }
  10. })
  11. })
  12. // 注意:放在路由前面
  13. app.use(koajwt({
  14. secret: 'Gopal_token'
  15. }).unless({ // 配置白名单
  16. path: [/\/api\/register/, /\/api\/login/]
  17. }))
  18. // routes
  19. app.use(index.routes(), index.allowedMethods())
  20. app.use(users.routes(), users.allowedMethods())
复制代码
必要注意的是以下几点:
      
    1. secret
    复制代码
    必须和
    1. sign
    复制代码
    时候保持划一  
  • 可以通过
    1. unless
    复制代码
    配置接口白名单,也就是哪些
    1. URL
    复制代码
    可以不用经过校验,像登岸/注册都可以不用校验  
  • 校验的中心件必要放在必要校验的路由前面,无法对前面的
    1. URL
    复制代码
    进行校验
演示

如果直接访问必要登录的接口,则会
  1. 401
复制代码

先注册,后登录,否则会提示用户名或者密码错误

登录后带上
  1. Authorization
复制代码
,可以正常访问,返回
  1. 200
复制代码
以及正确的数据

总结

本文总结了关于
  1. JWT
复制代码
鉴权相关的知识,并提供了一个
  1. koa2
复制代码
实现的简单
  1. demo
复制代码
,渴望对各人有所资助。
受制于篇幅,偶然机单独说下
  1. koa-jwt
复制代码
的源码,也相对比较简单~
本文
  1. demo
复制代码
地址:Client 和Server
参考

JSON Web Token 入门教程
Node.js 应用:Koa2 使用 JWT 进行鉴权
到此这篇关于Node使用koa2实现一个简单JWT鉴权的方法的文章就先容到这了,更多相关Node koa2 JWT鉴权内容请搜刮草根技术分享从前的文章或继承欣赏下面的相关文章渴望各人以后多多支持草根技术分享!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作