technology-note/java/其他/3.java-jwt生成与校验.md
2019-04-08 10:07:19 +08:00

102 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: '2019-02-28-15-50'
date: '2019/02/28 15:50'
title: 'java-jwt生成与校验'
tags: ['java', 'jwt', 'java-jwt', 'token']
categories:
- 'java'
- 'java工具集'
---
**本篇原创发布于:**[FleyX 的个人博客](http://www.tapme.top/blog/detail/2019-02-28-15-50)
# 什么是 JWT
  这里是[jwt 官方地址](https://jwt.io/),想了解更多的可以在这里查看。
  jwt 全称是**JSON Web Token**,从全称就可以看出 jwt 多用于认证方面的。这个东西定义了一种简洁的,自包含的,安全的方法用于通信双方以 json 对象的形式传递信息。其中**简洁****安全****传递信息**和 web 系统非常契合。
  jwt 实际上就是一个字符串,由以下三个部分构成(通过.分隔)
- Header 头部
- Payload 负载
- Signature 签名
因此一个 jwt 字符串都是如下的形式:
Header.Payload.Signature
## Header
  header 大多数情况下是只包含两个属性的 json 字符串,token 的类型("JWT")和用到的算法(比如 HS256,RS256,ES256 等)如下:
```json
{
"alg": "HS256",
"typ": "JWT"
}
```
然后用 Base64 将其编码就等到了 jwt 的第一部分
## Payload
  payload 顾名思义用于携带数据的,这里的数据有三种类型:
- Registered claims一组预定义的声明写在 jwt 标准中所有对其的实现都要准守。但不是强制要求携带。有以下几个字段iss(签发者),iat(创建时间),exp(过期时间),aud(签发者),sub(面向的用户)
- public claims随意定义通常存放用户 id用户类别等非铭感信息
这些数据也是 json 的形式,用 Base64 编码后就得到了 JWT 的第二个部分。
## Signature
  签名就是通过设定的秘钥和签名算法来对 header 和 payload 进行签名得到一个签名字符串,将这三个字符串组合起来就是 JWT 了。
# java 中使用
  通过`java-jwt`来实现,首先引入依赖:
```xml
<dependency>
<!-- 截止当前最新版本为3.7 -->
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.7.0</version>
</dependency>
```
## 签名
&emsp;&emsp;使用 HMC256代码入下
```java
private static final Algorithm ALGORITHM= Algorithm.HMAC256("security");
public static String encode() {
//通过秘钥生成一个算法
String token = JWT.create()
//设置签发者
.withIssuer("test")
//设置过期时间为一个小时
.withExpiresAt(new Date(System.currentTimeMillis()+60*60*1000))
//设置用户信息
.withClaim("name","小明")
.withClaim("age",20)
.sign(ALGORITHM);
return token;
}
```
## 验证
&emsp;&emsp;验证代码如下:
```java
//校验类
private static final JWTVerifier JWT_VERIFIER= JWT.require(ALGORITHM).withIssuer("test").build();
public static void decode(String token) {
DecodedJWT decodedJWT = JWT_VERIFIER.verify(token);
//如果校验失败会抛出异常
//payload可从decodeJWT中获取
}
```