浅谈JWT

JWT

常见的认证机制

HTTP Basic Auth

HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RESTful API 使用的最简单的认证方式,只需提供用户名密码即可,但由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的越来越少。因此,在开发对外开放的RESTful API时,尽量避免采用HTTP BasicAuth.

Cookie Auth

Cookie认证机制就是为一次请求认证在服务端创建—个Session对象,同时在客户端的浏览器端创建了一个Cookie对象;通过客户端带上来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会被删除。但可以通过修改cookie 的expire time使cookie在一定时间内有效。

浅谈JWT

OAuth

OAuth(开放授权,Open Authorization)是一个开放的授权标准,允许用户让第三方应用访问该用户在某web服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。如网站通过微信、微博登录等,主要用于第三方登录。

OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth上用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

下面是OAuth2.0的流程:

浅谈JWT

但是这种OAuth的认证机制适用于个人消费者类型的互联网产品,如社交类APP等应用,但是不适合拥有自有认证权限管理的企业应用。

缺点:过重。

Token Auth

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

Token Auth 认证流程

浅谈JWT

优点

比第一种方式更安全,比第二种方式更节约服务器资源,比第三种方式更加轻量。

具体,Token Auth的优点 ( Token机制相对于Cookie机制又有什么好处呢?):

  1. 支持跨域访问:Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输。
  2. 无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.

  3. 更适用CDN:可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可.

  4. 去糖:不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可心

  5. 更适用于移动应用:当你的客户端是一个原生平台 (iOS, Android, Windows 10等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Tokeni人证机制就会简单得多。
  6. CSRF:因为不再依赖于Cookie, 所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
  7. 性能:一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算的Token验证和解析要费时得多.

  8. 不需要为登录页面做特殊处理:如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理,

  9. 基于标准化;你的AP可以采用标准化的JSON Web Token (WT). 这个标准已经存在多个后端库 (.NET, Ruby.Java.Python,PHP)和多家公司的支持(如:Firebase,Google. Microsoft)

JWT简介

JSON Web Token (JWT)是一个开放的行业标准 (RFC 7519),它定义了一种简介的、自包含的协议格式,用于在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。

JWT可以使用HMAC算法或使用RSA的公钥/私钥对来签名,防止被篡改。

浅谈JWT

官网:https://jwt.io/

标准:https://tools.ietf.org/html/rfc7519

JWT令牌的优点:

  1. Jwt 基于 json,非常方便解析。
  2. 可以在令牌中自定义丰富的内容,易扩展。
  3. 通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高。
  4. 资源服务使用IWT可不依赖认证服务即可完成授权。

缺点:

  1. JWT令牌较长,古存储空间比较大。

JWT组成

浅谈JWT

一个JWT其实就是一个字符串,它由头部、负载与签名组成。

浅谈JWT

头部用于描述关于该JWT的最基本的信息,例如其类型(即WT)以及签名所用的算法(如HMAC SHA256或RSA) 等。

这也可以被表示成一个JSON对象。

{
"alg":"H5256"
"typ":"JWT"
}
  • alg:签名的算法,这里使用的算法是HS256算法
  • typ:是类型。

我们对头部的Json字符串进行BASE64编码(网上有很多在线编码的网站),编码后的字符串如下:

浅谈JWT

Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。

由于2的6次方等于64,所以每6个比特为个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。

JDK 中提供了非常方便的 BASE64EncoderBASE64Decoder用它们可以非常方便的完成基于BASE54 的编码和解码。

Payload 负载

第二部分是,就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分:

  • 标准中注册的声明(建议但不强制使用)
iss: jwt签发者
sub:jwt所面向的用户
aud:接收jwt的一方
exp:jwt的过期时间,这个过期时间必须要大于签发时间
nbf:定义在什么时间之前,该jwt都是不可用的。
iat: jwt的签发时间
jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
  • 公共的声明

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密。

  • 私有的声明

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

这个指的就是自定义的claim。比如下面那个举例中的name都属于自定的claim。

这些claim跟JWT标准规定的claim区别在于:JWT规定的claim,JWT的接收方在拿到JWT之后,都知道怎么对这些标准的claim进行验证(还不知道是否能够验证);

而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行。

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

其中sub 是标准声明,name是自定义的声明(公共或私有的)

然后将其进行BASE64编码,得到JWT的第二部分

浅谈JWT浅谈JWT

官网也给我们提示不要存放一些敏感的信息。

Signature 签名/签证

JWT的第三部分的信息是签名,这个签名信息包含三部分:

  1. header(BASE64之后)
  2. playload(BASE64之后)
  3. secret(盐,一定要保密)

这个部分需要base64加密后的header和base64加密后的payload使用,连接組成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分:

8HI-LodOncfVDnbKIPJJqLH998duF9DSDGkx3gRPNVI

将这三部分用,连接成—个完整的字符串,构成了最终的Jwt:

浅谈JWT

注意:secret 是保存在服务器端的,jwt 的签发生成也是在服务器端的,secret 就是用来进行 jwt 的签发和jwt 的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret,那就意味着客户端是可以自我签发 jwt了。

浅谈JWT

这是它官网的一个例子。

SpringBoot整合jwt

使用的这个依赖。

浅谈JWT

文档和源码

https://github.com/bearbrick0/SpringBoot-JJWT-DEMO

SpringSecurityOAuth2整合JWT

项目和文档:https://github.com/bearbrick0/SpringSecurityOauth2_demo

实现AcessToken转换成JwtToken。

浅谈JWT

拿着这段token去jwt官网解析,

浅谈JWT

单点登陆SSO

项目和文档:

https://github.com/bearbrick0/SpringSecurityOAuth2-SSO

浅谈JWT
浅谈JWT

Original: https://www.cnblogs.com/bearbrick0/p/16136429.html
Author: BearBrick0
Title: 浅谈JWT

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/572472/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【每天学一点-01】 在SpringBoot项目中使用Swagger2

    今天在做毕设的时候,发现在前后端分离的情况下,去调用接口数据时很不方便,然后回想过去,和同学一起做项目的时候,他负责后端,我负责前端,当时调用他的弄好的接口可以说是非常方便,主要是…

    Java 2023年6月5日
    083
  • 当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系

    哈喽大家好,我是阿Q! 事情是这个样子的…… 对话中的截图如下: 看了阿Q的解释,你是否也和”马小跳”一样存在疑问呢?请往👇看 我们…

    Java 2023年6月5日
    065
  • 软件装在D盘,实测有效

    C盘容量小,希望把所有软件都装到D盘,试过很多次,没什么作用。今天装MS全家桶的时候看到了个帖子,实测有效,Visio、Word、Excel、PowerPoint都装到了D盘原贴链…

    Java 2023年6月9日
    0143
  • redis5.0.4-cluster集群搭建及jedis客户端操作

    一、去官网下载redis5.0 https://redis.io/download 然后解压安装 $ tar xzf redis-5.0.4.tar.gz $ cd redis-5…

    Java 2023年6月9日
    0125
  • 深入学习SpringBoot

    快速上手SpringBoot 1.1 SpringBoot入门程序开发 SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来 简化Spring应用的 初始搭建…

    Java 2023年6月6日
    063
  • 还有人不懂布隆过滤器吗?

    还有人不懂布隆过滤器吗? 1.介绍 我们在使用缓存的时候都会不可避免的考虑到如何应对 缓存雪&#x5D29…

    Java 2023年6月8日
    090
  • Spring 基于注解配置bean之简单入门

    Spring 注解配置bean 复习注解相关的知识 啥是注解? 直接是一种特殊的标识符。可在源码或运行阶段起作用。 注解类型 元注解 如 **@Target** 自定义注解 Spr…

    Java 2023年6月7日
    044
  • Spring DefaultResourceLoader

    Spring DefaultResourceLoader Spring DefaultResourceLoader继承ResourceLoader接口,用来加载资源, 通过Reso…

    Java 2023年6月7日
    064
  • 客观的聊一聊,裁员这件糟心事

    时间在走,环境在变,互联网有点卷不动了; 捋一捋最近互联网上关于职场的热点:裁员,优化,毕业,向社会输送人才,求职;你方唱罢他方登场,持续横跳热搜; 年初到现在五月底,身边已经有好…

    Java 2023年6月15日
    078
  • remoting作成windows服务后一直无法读取配置文件,可能的原因之一。

    当然在这个无法读取配置文件,无法启动通道之前,你必须确认你的配置文件是正确的。正确的动态配置remoting的格式是: service >serverProviders &g…

    Java 2023年6月14日
    074
  • Spring框架源码干货分享之三级缓存和父子工厂

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正! 环境: spring5.X + idea 建议:学习过程中要开着源码一步一步过 Spri…

    Java 2023年6月5日
    080
  • 黑马头条–延迟任务精准发布文章

    1.添加任务 1.1.每次创建文章,就添加到任务中去 文章提交中调用添加任务方法 代码 @Override @Async public void addNewsToTask(Int…

    Java 2023年6月9日
    079
  • linux下安装jdk8

    1、下载jdk8安装包 2、拷贝到指定目录下(比如:/usr/package) 3、解压到安装目录下(比如:/usr/soft/java) tar -zxvf jdk-8u121-…

    Java 2023年6月8日
    067
  • Java 并发编程生产应用场景及实战

    背景介绍 为什么需要学习 Java 并发? 从提升性能角度来说 提升了对CPU的使用效率:目前生产的服务器大多数都是多核,标配的机器都是 8C/16G。操作系统会将不同的线程分配给…

    Java 2023年6月15日
    088
  • Spring boot——JMX 监控

    spring.jmx.enabled=true 在命令行中执行 jconsole命令启动”Java管理和监视控制台”,然后选择org.springframe…

    Java 2023年5月30日
    077
  • 文件输入/输出流

    文件输入/输出流程序 运行期间,大部分数据都被存储在 内存中,当程序结束或被关闭时,存储在内存中的数据将会 消失。如果要 永久保存数据,那么最好的办法就是把数据保存到 磁盘的文件中…

    Java 2023年6月9日
    063
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球