本章节讨论 jwt 在 spring boot 中的应用。意在快速入门 jwt。

  • java jdk1.8
  • maven 3.2+
  • spring boot 2.0+

JSON Web Token(JWT) 他是一个用于 Web 身份验证的令牌。

1 JWT 概述

1.1 什么是JWT

直观的理解 JWT 就是一串字符串,如下(来自于 JWT.IO):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

细心的你可能会发现字符串是有3个独立的字符串使用.号组合而成,前两个字符串是 Base64 编码,最后一个字符串是一个加密后的字符串。

序号 字符串
1 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
2 eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
3 SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT 使用以上3个字符串组成一个字符串,以 xxxxx.yyyyyy.zzzzz 的形式传输给认证服务器

xxxxx.yyyyyy.zzzzz 表示为 Header.Payload.Signature

Header=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload=eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

Signature=SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

我们使用 JWT Debuger 把信息解码可以看出:

1.1.1 Header

Header 头信息,以 json 字符串实现,并压缩成 Base64URL 编码字符串传输

{
"alg": "HS256",
"typ": "JWT"
}

上面代码中,alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。

1.1.2 Payload

Payload 负载,以 json 字符串实现,并压缩成 Base64编码字符串传输

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}

官方对 json 内容节点给出了一些建议,我个人觉得意义不大,况且那个建议字段完全是看不出任何含义的缩写。比如 iss、exp、sub、aud、nbf、iat、jti。当然如果大家都能共同遵守,也不存在这些问题。

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

1.1.3 Signature

VERIFY SIGNATURE 签名,在服务端指定一个秘钥,把签名两个 json 字符串使用下面方法加密而成的

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
only-save-in-server-secret)

值得注意的是,使用JWT 推荐使用 HTTPS 加密协议

1.1.4 Base64URL

BASE64URL是一种在BASE64的基础上编码形成新的加密方式,为了编码能在网络中安全顺畅传输,需要对BASE64进行的编码,特别是互联网中。

1.2 JWT 是如何工作的

为了能够支持跨域,通常 JWT 的字符串 xxxxx.yyyyyy.zzzzz 通过 Http 的 Head 发送

Authorization: Bearer <token>

也可以放在 Post 数据体重。

2 Spring Boot JWT 示例

在 JWT 官方可以看到,maven: io.jsonwebtoken / jjwt / 0.9.0 这个库是支持最全的。

2.1 新建 Spring Boot Maven 示例工程项目

  1. File > New > Project,如下图选择 Spring Initializr 然后点击 【Next】下一步
  2. 填写 GroupId(包名)、Artifact(项目名) 即可。点击 下一步

    groupId=com.fishpro

    artifactId=jwt
  3. 选择依赖 Spring Web Starter 前面打钩。
  4. 项目名设置为 spring-boot-study-jwt.

2.2 依赖引入 Pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fishpro</groupId>
<artifactId>jwt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jwt</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

2.4 编写 JWT 生成与验证代码

本章节知识学习 JWT,不涉及其他知识点,故我们之间在 JwtApplication.java 中来编写代码

package com.fishpro.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.*; @SpringBootApplication
public class JwtApplication { public static void main(String[] args) { SpringApplication.run(JwtApplication.class, args);
String token=createJWTToken();//获取生成的Token
verifyJWTToken(token);//验证生成的Token
} /**
* 生成 JWT Token
* */
private static String createJWTToken() throws JWTCreationException {
String secret="secret";//假设服务端秘钥
Algorithm algorithm = Algorithm.HMAC256(secret);
//jwt 头部信息
Map<String,Object> map=new HashMap<>();
map.put("alg","HS256");
map.put("typ","JWT"); Date nowDate = new Date();
Date expireDate = AddDate(nowDate,2*60);//120 分钟过期 String token= JWT.create()
.withHeader(map)
.withIssuer("SERVICE") //对应 paylaod iss 节点:签发人
.withClaim("loginName","fishpro")
.withSubject("this is a token demo")//对应 paylaod sub 节点:主题
.withAudience("Client")//对应 paylaod aud 节点:受众
.withIssuedAt(nowDate)//对应 paylaod iat 节点:生效时间
.withExpiresAt(expireDate) //对应 paylaod exp 签发人 节点:过期时间
.sign(algorithm);
return token;
} /**
* 验证 token
* */
private static void verifyJWTToken(String token) throws JWTVerificationException {
Algorithm algorithm=Algorithm.HMAC256("secret");
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("SERVICE")
.build(); DecodedJWT jwt =verifier.verify(token);
String subject=jwt.getSubject();
Map<String,Claim> claims=jwt.getClaims();
Claim claim = claims.get("loginName");
System.out.println("自定义 claim:"+claim.asString()); List<String> audience = jwt.getAudience();
System.out.println("subject 值:"+subject);
System.out.println("audience 值:"+audience.get(0));
} /**
* 时间加减法
* */
private static Date AddDate(Date date,Integer minute){
if(null==date)
date=new Date();
Calendar cal=new GregorianCalendar();
cal.setTime(date);
cal.add(Calendar.MINUTE, minute);
return cal.getTime(); } }

2.5 演示效果

右键 JwtApplication 选择 Run JwtApplication ,观察 console 窗口

Spring Boot JWT 快速入门的更多相关文章

  1. Spring Boot:快速入门教程

    什么是Spring Boot? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人 ...

  2. Spring Boot【快速入门】简单案例

    Spring Boot[快速入门]   Spring Boot 概述 Build Anything with Spring Boot:Spring Boot is the starting point ...

  3. Spring Boot框架——快速入门

    Spring Boot是Spring 全家桶非常重要的一个模块,通过 Spring Boot 可以快速搭建一个基于 Spring 的 Java 应用程序,Spring Boot 对常用的第三方库提供了 ...

  4. Spring Boot【快速入门】

    Spring Boot 概述 Build Anything with Spring Boot:Spring Boot is the starting point for building all Sp ...

  5. (Spring Boot框架)快速入门

    Spring Boot 系列文章推荐 Spring Boot 入门 Spring Boot 属性配置和使用 Spring Boot 集成MyBatis Spring Boot 静态资源处理 今天介绍一 ...

  6. 【转载】Spring Boot【快速入门】2019.05.19

    原文出处:https://www.cnblogs.com/wmyskxz/p/9010832.html   Spring Boot 概述 Build Anything with Spring Boot ...

  7. Spring Boot WebFlux 快速入门实践

    02:WebFlux 快速入门实践 Spring Boot 2.0 spring.io 官网有句醒目的话是: BUILD ANYTHING WITH SPRING BOOT Spring Boot ( ...

  8. Spring Boot:快速入门

    上一篇讲述什么是Spring Boot,这一篇讲解怎么使用IDE工具快速搭建起来独立项目. 一.构建方式 快速搭建项目有三种方式,官方也有答案给到我们: 二.构建前准备 想要使用IDE运行起来自己的S ...

  9. Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门

    1. 什么是响应式编程 在计算机中,响应式编程或反应式编程(英语:Reactive programming)是一种面向数据流和变化传播的编程范式.这意味着可以在编程语言中很方便地表达静态或动态的数据流 ...

随机推荐

  1. 【资料】哈代&拉马努金相关,悼文,哈佛演讲,及各种杂七杂八资料整理

    悼文和哈佛演讲,因为有一堆公式所以实在懒得放lofter了. 信件和其他资料翻译在这里放个备份,基本上来自<Ramanujan:Letters and commentary>和<Ra ...

  2. url中的参数加密

    有时候我们需要在地址栏传输一些信息,比如查询数据的时候,传一个参数location.href = "/admin/extract?name="+"参数aaa"’ ...

  3. EAC3 enhanced channel coupling

    Enhanced channel coupling是一种spatial coding 技术,在传统的channel coupling的基础上添加了phase compensation, de-corr ...

  4. 每天进步一点点------MicroBlaze

             有了前面两个实例的铺垫,下面这个工程就要带大家尝试搭建一个基于MicroBlaze的应用.特权同学也是第一次接插Xilinx的嵌入式开发平台,跑了一个流程下来,正如所料,和Alter ...

  5. ACM的探索之Everything is Generated In Equal Probability! 后序补充丫!

    Problem Desciption: 百度翻译后的汉化: 参见博客:https://www.cnblogs.com/zxcoder/p/11253099.html https://blog.csdn ...

  6. Java8 Time API与老Date之间的转换

    前面我已经总结了Java8 Time API常用的一些方法.封装的工具类,可是最近需要对一个比较老的项目进行重构,大致看了一下使用的Jdk还是7而且里面的时间工具类还是使用的Date和Calendar ...

  7. 动态设置微信小程序 navigationBarTitle 的值

    wx.setNavigationBarTitle({ title:' 动态值 ' })

  8. 【vue】 router.beforeEach

    import store from '@/store' const Vue = require('vue') const Router = require('vue-router') Vue.use( ...

  9. android底部导航栏实现

    第一种用radiobutton实现 https://wizardforcel.gitbooks.io/w3school-android/content/75.html 布局文件,使用radiogrou ...

  10. Java - 字符串操作

    字符串常用操作如下 public static void main(String[] args) { /** * 创建字符串 */ String s1="zifuchuan123" ...