首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >nodejs实现jwt_2023-03-01

nodejs实现jwt_2023-03-01

原创
作者头像
用户10377376
发布于 2023-03-01 13:36:06
发布于 2023-03-01 13:36:06
92900
代码可运行
举报
文章被收录于专栏:前端面试题17前端面试题17
运行总次数:0
代码可运行

jwt是json web token的简称,本文介绍它的原理,最后后端用nodejs自己实现如何为客户端生成令牌token和校验token

1.为什么需要会话管理

我们用nodejs为前端或者其他服务提供resful接口时,http协议他是一个无状态的协议,有时候我们需要根据这个请求的上下获取具体的用户是否有权限,针对用户的上下文进行操作。所以出现了cookies session还有jwt这几种技术的出现, 都是对HTTP协议的一个补充。使得我们可以用HTTP协议+状态管理构建一个的面向用户的WEB应用。

2.session和cookies

session和cookies是有联系的,session就是服务端在客户端cookies种下的session_id, 服务端保存session_id所对应的当前用户所有的状态信息。每次客户端请求服务端都带上cookies中的session_id, 服务端判断是否有具体的用户信息,如果没有就去调整登录。

  • cookies安全性不好,攻击者可以通过获取本地cookies进行欺骗或者利用cookies进行CSRF攻击。
  • cookies在多个域名下,会存在跨域问题
  • session的信息是保存在服务端上面的,当我们node.js在stke部署多台机器的时候,需要解决共享session,所以引出来session持久化问题,所以session不支持分布式架构,无法支持横向扩展,只能通过数据库来保存会话数据实现共享。如果持久层失败会出现认证失败。

3.jwt的定义

jwt是json web token的全称,他解决了session以上的问题,优点是服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展,什么情况下使用jwt比较合适,我觉得就是授权这个场景,因为jwt使用起来轻便,开销小,后端无状态,所以使用比较广泛。

4.jwt的原理

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "姓名": "张三",
  "角色": "管理员",
  "到期时间": "2018年7月1日0点0分"
}

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。

5.jwt的认证流程

流程说明:

  1. 浏览器发起请求登陆,携带用户名和密码;
  2. 服务端根据用户名和明码到数据库验证身份,根据算法,将用户标识符打包生成 token,
  3. 服务器返回JWT信息给浏览器,JWT不应该包含敏感信息,这是很重要的一点
  4. 浏览器发起请求获取用户资料,把刚刚拿到的 token一起发送给服务器,一般放在header里面,字段为authorization
  5. 服务器发现数据中有 token,decode token的信息,然后再次签名,验明正身;
  6. 服务器返回该用户的用户资料;
  7. 服务器可以在payload设置过期时间, 如果过期了,可以让客户端重新发起验证。

6.jwt的数据结构

jwt包含了使用.风格的三个部分

Header头部

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "alg": "HS256", "typ": "JWT"}   
// algorithm => HMAC SHA256
// type => JWT

这是固定的写法,alg表面要用的是HS256算法

Payload 负载、载荷,JWT 规定了7个官方字段

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

除了这七个,可以自定义,比如过期时间

Signature 签名

对前两部分header和payload进行签名,防止数据篡改

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

secret是一段字符串,后端保存,需要注意的是JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。

7.jwt使用方式

HTTP 请求的头信息Authorization字段里面, Bearer也是规定好的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Authorization: Bearer <token>

通过url传输(不推荐)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
http://www.xxx.com/pwa?token=xxxxx

如果是post请求也可以放在请求体中

8.在koa项目中使用

可以使用现成库,jwt-simple 或者 jsonwebtoken

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let Koa = require('koa');
let Router = require('koa-router');
let bodyparser = require('koa-bodyparser');
let jwt = require('jwt-simple');
let router = new Router()
let app = new Koa();
app.use(bodyparser());
// 可以自己自定义
let secret;
// 验证是否登陆
router.post('/login',async(ctx)=>{ 
    let {username,password} = ctx.request.body;
    if(username === 'admin' && password === 'admin'){
       // 通常会查数据库,这里简单的演示
       let token =  jwt.encode(username, secret);
       ctx.body = {
            code:200,
            username,
            token,
       }
    }
});
// 验证是否有权限
router.get('/validate',async(ctx)=>{ 
    let Authorization = ctx.get('authorization')
    let [,token] = Authorization.split(' ');
    if(token){
        try{
            let r = jwt.decode(token,secret);
            ctx.body = {
                code:200,
                username:r,
                token
            }
        }catch(e){
            ctx.body = {
                code:401,
                data:'没有登陆'
            }
        }
    }else{
        ctx.body = {
            code:401,
            data:'没有登陆'
        }
    }

});
app.use(router.routes());
app.listen(4000);
  1. 实现两个接口 一个是/login 验证是否登录,一个是 validate,验证是否有权限
  2. 请求login接口的时候,客户端带username和password, 后端一般会查数据库,验证是否存在当前用户,如果存在则为username进行签名,千万不要给password这些敏感信息也带进来签名
  3. 客户端接收后端给的token令牌,再请求其他接口,比如这个例子的/validate的时候,ajax请求的时候,可以在header指定authorization字段,后端拿到token进行decode,然后将header和payload进行再一次的签名,如果前后的签名一致,说明没有被篡改过,则权限验证通过。因为是同步的过程,所以可以用try catch来捕捉错误

9.原理的实现

  1. sha256哈希算法,可以用nodejs的内置加密模块crypto, 生成base64字符串,要注意的是生成base64需要为+ - = 做一下替换,=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。
  2. token令牌的组成是header, payload和sigin的通过.来组成
  3. base64urlUnescape的解码是固定写法,decode出base64的内容
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let myJwt = {
    sign(content,secret){
        let r = crypto.createHmac('sha256',secret).update(content).digest('base64');
        return this.base64urlEscape(r)
    },
    base64urlEscape(str){
        return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
    },
    toBase64(content){
        return this.base64urlEscape(Buffer.from(JSON.stringify(content)).toString('base64'))
    },
    encode(username,secret){
        let header = this.toBase64({ typ: 'JWT', alg: 'HS256' });
        let content = this.toBase64(username);
        let sign = this.sign([header,content].join('.'),secret);
        return  [header,content,sign].join('.')
    },
    base64urlUnescape(str) {
        str += new Array(5 - str.length % 4).join('=');
        return str.replace(/\-/g, '+').replace(/_/g, '/');
    },
    decode(token,secret){
        let [header,content,sign] = token.split('.');
        let newSign = this.sign([header,content].join('.'),secret);
        if(sign === newSign){
            return Buffer.from(this.base64urlUnescape(content),'base64').toString();
        }else{
            throw new Error('被篡改')
        }
    }
}

10.jwt的优缺点

  1. JWT默认不加密,但可以加密。生成原始令牌后,可以使用改令牌再次对其进行加密。
  2. 当JWT未加密方法是,一些私密数据无法通过JWT传输。
  3. JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数。
  4. JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。
  5. JWT本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行进行身份验证
  6. 为了减少盗用和窃取,JWT不建议使用HTTP协议来传输代码,而是使用加密的HTTPS协议进行传输。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
博客SEO优化全攻略:提升搜索排名的实用技巧
在正式学习SEO优化技巧之前,我们需要了解SEO的基本概念和搜索引擎的工作原理。SEO(Search Engine Optimization,搜索引擎优化)是指通过优化网站内容和结构,使其更符合搜索引擎排名规则,从而提高网站在自然搜索结果中的排名,获取更多流量的一系列技术和过程。相比付费推广,SEO能够带来成本低廉且持续的免费流量,对于大学生运营博客而言是非常有价值的流量来源。
大熊计算机
2025/07/14
1420
如何创作SEO优质文章内容?高质量文章怎么写?
当一个网站做好之后,那么就要完善内容,其中就要涉及到文章内容的创作,那么文章内容要怎么写呢?写文章时不必太在意内容的多少,关键是要注意长尾关键词的布局。写作时不一定要追求高大尚,也不一定要长篇大论,我们只要围绕标题把内容清晰的表达出来即可,让用户可以明白就好。
雾海梦曦
2022/11/14
6470
如何创作SEO优质文章内容?高质量文章怎么写?
网站SEO优化步骤超详细完整版教程
一、准备 1、心态 长时间,不断学习。学习建站、基础代码、SEO全过程、实际操作并成功。
宜轩
2022/12/29
2.1K0
网络编辑应该熟知的7个基本SEO技巧
  网络编辑和报纸、杂志编辑最大的不同是我们需要大量网络技术知识,还需要为我们所发布的新闻的点击量负责。一个好的网编,绝对不仅仅是ctrl+c、 ctrl+v,不仅要求我们有很强的新闻敏感性,在大事件来临或者将来临的时候就有所察觉并在发布新闻的时候有所动作甚至提前布局,也要求我们懂基本的网 络新闻传播规律以及SEO基础。只有这样,我们才能在竞争激烈的网络新闻传播中争得主动权,从百度和google获取更多的流量。
大葡萄
2019/04/09
4270
网络编辑应该熟知的7个基本SEO技巧
如何做好SEO(搜索引擎优化)
随着互联网的迅速发展,更多的企业开始关注SEO(Search Engine Optimization,搜索引擎优化)。SEO是通过改进网站的结构和内容,提高网站在搜索引擎结果页面的排名,从而吸引更多的有目的性的访问者。本文将深入探讨如何做好SEO并提供详细的指导。
老K博客
2023/12/18
1K0
出现这些情况说明是网站过度优化
可能昨天你网站很多关键词都有一定排名,第二天突然排名下降很厉害,甚至没有排名情况,这个时候就需要特别注意了。
小唐同学.
2022/02/23
1.2K0
要想网站长尾关键词排名多,文章优化少不了!
  导读:经常有客户问起这个问题“网站是更新原创文章,网站优化还是不见起色”,对于这个问题,虽然说百度调整了算法,越来越重视网站内容建设,喜欢高质量并且原创的文章,于是许多企业找专门的写手撰写高质量文
深度网
2021/06/24
3460
要想网站长尾关键词排名多,文章优化少不了!
不是所有网站都要高质量内容
高质量内容,为什么不是所有网站都需要?简单地讲,网站内容涉及文字,图片,视频,音频,动画效果等等组成。最原始的搜索引擎只收录文字,即使你试图优化图像和视频,那些被索引的图像和视频只是收录相关文字。这是一个不得不面对的事实,搜索引擎天生喜欢文字,通过网站文字分析,以此为基础对网站评估,除了文字之外其它任何内容都会让搜索引擎变得很复杂。站长拥有一个非常好的网站,就是没有太多文字,但在搜索引擎排名处于劣势,反而不是那些内容较多的不太有用的网站。
林雍岷
2019/07/03
1.1K0
「技巧」5个SEO基础技巧知识
献给未来的我 每天的坚持 只有经历地狱般的磨难, 才能炼出创造天堂的力量; 只有流过血的手指, 才能弹奏出世间的绝唱。 SEO的发展随着时间不断的普及,很多SEO知识、技巧越来越多的人知道,可以说SEOer的技能已经快到瓶颈了,你知道的或不知道的,别人都有可能知道。 今天,给大家分享5个SEO技巧内容,这些技巧都源于基础,希望能够对各位同学有所帮助。 — — 及时当勉励,岁月不待人。 SEO基础技巧 时本文总计约1500个字左右,需要花 5 分钟以上仔细阅读。 来看最近的一些数据: 93%的在线体验是从搜
黄伟SEO
2018/05/17
7630
撰写高质量技术文章的实践指南【从选题到读者互动的全流程经验分享】
撰写技术文章不仅是分享知识的重要方式,也是个人技术提升和职业发展的有力工具。以下是我在撰写技术文章过程中的一些经验和心得,希望能对你有所帮助。
一键难忘
2024/07/21
1.2K2
百度 SEO:不是玄学,是科学与艺术的 “恋爱”
恩爸编程
2024/12/12
920
百度 SEO:不是玄学,是科学与艺术的 “恋爱”
6种高质量外链的内容类型推荐
做网站SEO项目的运营人员,为得到高质量的外链往往会费尽心思。而高质量外链往往会依托于优良的内容,项目的类型不同,需要的内容承载也不同。如果内容比较单一,那么指挥让你在某一个领域获得一种稳定的链接,但是通常情况下,SEO的外链建设讲究多元化。
安邦运维ruangseo
2019/08/02
9910
SEO技巧汇集
每个人都喜欢好用的技巧,对吗?这里有55个用于搜索引擎优化的小技巧,甚至你的老妈用起来都易如反掌。哦,不是我的老妈,但你明白我的意思。这意味着网页设计师和SEO新手中大部分人都能迅速上手,没有任何困难。
全栈程序员站长
2022/07/15
4120
【SEO的优化技巧和方法】——让你的文章在搜索引擎中脱颖而出!
🔍搜索引擎优化(SEO)是一种提高网站在搜索结果中排名的技术,对于自媒体平台来说,拥有高质量的内容是吸引用户的关键。那么,如何让你的自媒体文章在众多内容中脱颖而出呢?本文将为你介绍一些实用的SEO优化技巧和方法,让你的文章更容易被搜索引擎发现!
用户10637139
2024/04/27
2430
「SEO」页面搜索引擎优化详细解说
做个内心阳光的人,不忧伤,不心急,坚强,向上,靠近阳光,成为更好的自己。你不需要别人过多的称赞,因为你自己知道自己有多好。内心的强大,永远胜过外表的浮华。 今天给大家讲解下一个页面该如何进行SEO优化,一个页面优化该注意哪些细节,以及有什么样的操作手法。 — — 及时当勉励,岁月不待人。 页面搜索引擎优化 时本文总计约 2200 个字左右,需要花 6 分钟以上仔细阅读。 1 使用搜索引擎友好的URL 对于谷歌优化来说,谷歌已经表示,网址中的前3-5个字是更重要的。那么对应中文搜索引擎来说,百度、好搜等等搜
黄伟SEO
2018/05/17
1.1K0
怎样写好一篇高质量的技术文章?
原则一:一个人的影响力不是由他的财富决定,也不是由他的智力决定,而是由他能帮助多少人决定。
一个会写诗的程序员
2020/05/08
1.4K0
网站SEO提高百度谷歌收录和排名
SEO并不深奥,SEO最重要的是要有耐心、恒心。不少新手建站时都会遇到网站SEO问题,如何提高百度、Google等搜索引擎的收录和排名,是一件很头疼的事。本文将从域名、链接、标题、关键词、外链等多个方面谈谈网站SEO的方法,希望对建站新手有所帮助。
星哥玩云
2022/08/13
9850
Google网站排名多久能到首页?
每一个企业都希望自己的外贸网站排名可以在短时间内排上Google首页,那Google网站排名多久能到首页呢?一尘SEO可以告诉大家的是,Google排名需要一定的时间和周期去判定,SEO是一个持续积累的过程,并不像SEM一样立竿见影。影响Google排名的因素非常多,例如:
一尘SEO
2020/09/02
2.4K0
Google网站排名多久能到首页?
Web前端如何进行SEO结构优化
做前端的肯定离不开SEO,无论您是专职的SEOer还是其他什么别的,只要设计到前端就避不开SEO,大大小小做了几十个企业网站和个人博客网站建设的我,对与SEO仍然出于小白阶段,虽说前段时间博客也终于达到了2+,但是最近又回到了1。。。挺惨的哈,结合百度资料、CSDN等权威信息,介绍一下关于网页前端SEO结构性优化的文章,供参考,并共勉!
李洋博客
2021/06/15
1.1K0
7.ChatGPT与SEO - 优化内容策略【7/10】
在当今的数字化时代,搜索引擎优化(SEO)已成为数字营销中不可或缺的一部分。它不仅帮助企业提高在线可见性,还直接影响着网站的流量、品牌知名度和最终的销售转化。SEO通过优化网站内容和结构,使其在搜索引擎结果页(SERP)上获得更高的排名,从而吸引更多的潜在客户。
正在走向自律
2024/12/18
2430
7.ChatGPT与SEO - 优化内容策略【7/10】
推荐阅读
相关推荐
博客SEO优化全攻略:提升搜索排名的实用技巧
更多 >
LV.0
这个人很懒,什么都没有留下~
交个朋友
加入云原生工作实战群
云原生落地实践 技术难题攻坚探讨
加入腾讯云技术交流站
洞悉AI新动向 Get大咖技术交流群
加入MCP头号玩家交流群
云原生运维进阶交流 MCP认证经验分享
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验