前言:

现在越来越多的项目或多或少会用到JWT,为什么会出现使用JWT这样的场景的呢?

假设现在有一个APP,后台是分布式系统。APP的首页模块部署在上海机房的服务器上,子页面模块部署在深圳机房的服务器上。此时你从首页登录了该APP,然后跳转到子页面模块。session在两个机房之间不能同步,用户是否需要重新登录?

传统的方式(cookie+session)需要重新登录,用户体验不好。session共享(在多台物理机之间传输和复制session)方式对网络IO的压力大,延迟太长,用户体验也不好。

说到这大家可能会想到,用服务器的session_id存储到cookies中也能做到,为什么非要用token呢?网上有许多文章来比较token和session的优缺点,其实,开发web应用的话用哪种都行。但如果是开发api接口,前后端分离,最好使用token,为什么这么说呢,因为session+cookies是基于web的。但是针对 api接口,可能会考虑到移动端,app是没有cookies和session的。

Session方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。

  而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端

原理:

JSON Web Token(缩写 JWT)

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,以后,用户与服务端通信的时候,都要发回这个 JSON 对象。

服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。

服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。

组合:

JWT 的三个部分依次是:Header(头部)、Payload(负载)、Signature(签名)

写成一行,就是下面的样子。

Header.Payload.Signature

一、Header

header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)

        {
"alg": "HS256", //alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256)
"typ": "JWT" //typ属性表示这个令牌(token)的类型(type)
}

然后用Base64对这个JSON编码就得到JWT的第一部分

二、Payload

JWT的第二部分是payload,它包含声明(要求)。声明是关于实体(通常是用户)和其他数据的声明

JWT 规定了7个官方字段

  • iss (issuer):签发人
  • exp (expiration time):过期时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子

{
"sub": "",
"name": "John Doe",
"admin": true
}
注意,不要在JWT的payload或header中放置敏感信息,除非它们是加密的

三、Signature

Signature 部分是对前两部分的签名,防止数据篡改。签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。

为了得到签名部分,你必须有编码过的header、编码过的payload、一个秘钥,签名算法是header中指定的那个,然对它们签名即可。按照下面的公式产生签名。

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

开始:

一、客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。

Authorization: Bearer <token>

二、JWT 就放在 POST 请求的数据体里面,那么跨源资源共享(CORS)将不会成为问题,因为它不使用cookie

1.应用(或者客户端)想授权服务器请求授权。例如,如果用授权码流程的话,就是/oauth/authorize

2.当授权被许可以后,授权服务器返回一个access token给应用

3.应用使用access token访问受保护的资源(比如:API)

特点:

1.JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。

2.JWT 不加密的情况下,不能将秘密数据写入 JWT。

3.JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

4.JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

注意:

JWT 是 JSON 格式的被加密了的字符串

JWT 的核心是密钥,就是 JSON 数据。这是你关心的,并希望安全传递出去的数据。JWT 如何做到这一点,并使你信任它,就是加密签名。

被篡改之后

总结:

参考官方文档:JSON Web Tokens

初步认识JWT的更多相关文章

  1. 初步理解JWT并实践使用

    原文:https://www.jianshu.com/p/2fdc20a42c41 JWT是一种用于双方之间传递安全信息的简洁的.URL安全的表述性声明规范.JWT作为一个开放的标准(RFC 7519 ...

  2. kbmMW集成JWT

    如果对JWT不熟悉,需要先补下功课:初步理解JWT并实践使用 然后找到开源项目:https://github.com/paolo-rossi/delphi-jose-jwt

  3. 认证授权方案之JwtBearer认证

    1.前言 回顾:认证方案之初步认识JWT 在现代Web应用程序中,即分为前端与后端两大部分.当前前后端的趋势日益剧增,前端设备(手机.平板.电脑.及其他设备)层出不穷.因此,为了方便满足前端设备与后端 ...

  4. 基于.NetCore3.1系列 ——认证授权方案之Swagger加锁

    一.前言 在之前的使用Swagger做Api文档中,我们已经使用Swagger进行开发接口文档,以及更加方便的使用.这一转换,让更多的接口可以以通俗易懂的方式展现给开发人员.而在后续的内容中,为了对a ...

  5. JWT的初步了解以及session、cookie机制

    1.什么是状态保持? 想要了解JWT,首先需要知道什么是状态保持,举一个例子来说:无论是在web上还是在手机app上,我们都可以以游客的身份访问,此时都会有登录/注册字眼,当我们登录之后,就会是我们的 ...

  6. 从壹开始前后端分离[.NetCore] 37 ║JWT完美实现权限与接口的动态分配

    缘起 本文已经有了对应的管理后台,地址:https://github.com/anjoy8/Blog.Admin 哈喽大家好呀!又过去一周啦,这些天小伙伴们有没有学习呀,已经有一周没有更新文章了,不过 ...

  7. Spring Security构建Rest服务-1300-Spring Security OAuth开发APP认证框架之JWT实现单点登录

    基于JWT实现SSO 在淘宝( https://www.taobao.com )上点击登录,已经跳到了 https://login.taobao.com,这是又一个服务器.只要在淘宝登录了,就能直接访 ...

  8. spring jwt springboot RESTful API认证方式

    RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authentication)和授权(Authorization)过程,保证API的安全性. Authenticatio ...

  9. SpringBoot系列 - 集成JWT实现接口权限认证

    会飞的污熊 2018-01-22 16173 阅读 spring jwt springboot RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authenticati ...

随机推荐

  1. HlpViewer.exe 单独打开

    1.在桌面新建一个快捷键 2.添加HlpViewer.exe 的本地地址 3.在添加的地址后面添加 /catalogName VisualStudio12 4.保存快捷键即可 列: 桌面右键-> ...

  2. 弃用 wget, 拥抱多线程下载 axel

    0x00 事件 对于在 Linux 的下载工具而言,比较常用的就是 wget 或者 curl,吾也一直用 wget 的方式进行网络上的资源下载.偶然发现了 axel 这个支持多线程的下载工具,试用了几 ...

  3. 神盘GCCX,2019必撸大毛!

    自从今年5月转型投资以来,已经很少薅羊毛了! 不是不撸,是因为一般的羊毛我真看不上! 撸羊毛能不能发财,能不能日入几百几千! 答案是,可以! 干羊毛,像趣步,云钱包,云比特,环保币,很多人都发财了!前 ...

  4. Could not determine type for java util List

    问题场景:在实体类中需要使用List集合存储字段,启动时找不到List类型 问题解决:在字段上添加@ElementColletion(targetClass=String.class)表示是一个集合映 ...

  5. Kafka 原理和实战

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/bV8AhqAjQp4a_iXRfobkCQ作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双语 ...

  6. sql server 日期近一年,同比

    --近一年 ), , , ) SELECT CONVERT(VARCHAR, DATEADD(day, -DAY(GETDATE()), , ) --同比 ), , , ) SELECT CONVER ...

  7. [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)

    [FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...

  8. 2019牛客暑期多校训练营(第十场)J - Wood Processing (斜率优化DP)

    >传送门< 题意 $n$个宽度为$w_{i}$,高为$h_{i}$ 的 木块,要求分成$k$组,对于每组内的所有木块,高度都变为组内最低木块的高度,宽度保持不变,求变化的最小面积. 分析 ...

  9. Flink的TaskManager启动(源码分析)

    通过启动脚本已经找到了TaskManager 的启动类org.apache.flink.runtime.taskexecutor.TaskManagerRunner 来看一下它的main方法中 最后被 ...

  10. MongoDB 数据库的学习与使用

    MongoDB 数据库 一.MongoDB 简介(了解) ​ MongoDB 数据库是一种 NOSQL 数据库,NOSQL 数据库不是这几年才有的,从数据库的初期发展就以及存在了 NOSQL 数据库. ...