JSON Web Token jwt使用笔记 token

硅谷探秘者 2114 0 0

什么是jwt?

java代码测试

什么是jwt?

Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

关于jwt的应用,实现原理,以及具体细节自行百度吧!devil

java代码测试

pom文件

<dependency>
		    <groupId>com.auth0</groupId>
		    <artifactId>java-jwt</artifactId>
		    <version>3.8.1</version>
		</dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JwtUtil {
    /**
     * 	加密密文
     */
    public static final String JWT_SECRET = "secret";
    public static final int JWT_TTL = 60*1000*60*24;  //millisecond

    /**
     * 	由字符串生成加密key
     *
     * @return
     */
    public static SecretKey generalKey() {
        // 本地的密码解码
        byte[] encodedKey = Base64.decodeBase64(JWT_SECRET);
        // 根据给定的字节数组使用AES加密算法构造一个密钥
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }


    /**
     * 	创建jwt
     */
    public static String createJWT(String id, String issuer, String subject, long ttlMillis, Map<String, Object> claims) throws Exception {

        // 指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成JWT的时间
        long nowMillis = System.currentTimeMillis();

        // 生成签名的时候使用的秘钥secret,切记这个秘钥不能外露哦。它就是你服务端的私钥,在任何场景都不应该流露出去。
        // 一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
        SecretKey key = generalKey();

        // 下面就是在为payload添加各种标准声明和私有声明了
        JwtBuilder builder = Jwts.builder() // 这里其实就是new一个JwtBuilder,设置jwt的body
                .setClaims(claims)          // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
                .setId(id)                  // 设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
                .setIssuedAt(new Date(nowMillis))           // iat: jwt的签发时间
                .setIssuer(issuer)          // issuer:jwt签发人
                .setSubject(subject)        // sub(Subject):代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
                .signWith(signatureAlgorithm, key); // 设置签名使用的签名算法和签名使用的秘钥

        // 设置过期时间
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            builder.setExpiration(new Date(expMillis));
        }
        return builder.compact();
    }

    /**
     *	 解密jwt
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey key = generalKey();  //签名秘钥,和生成的签名的秘钥一模一样
        Claims claims = Jwts.parser()  //得到DefaultJwtParser
                .setSigningKey(key)                 //设置签名的秘钥
                .parseClaimsJws(jwt).getBody();     //设置需要解析的jwt
        return claims;
    }


    public static void main(String[] args) {
        String subject ="";
        // 创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", "1");
        claims.put("title", "title");
        try {
            String jwt = JwtUtil.createJWT(UUID.randomUUID().toString(), "Anson", subject, JWT_TTL, claims);
            System.out.println("JWT:" + jwt);
            System.out.println("length:"+jwt.length());
            System.out.println("解密");
            Claims c = JwtUtil.parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIiLCJpc3MiOiJBbnNvbiIsImlkIjoiMSIsInRpdGxlIjoidGl0bGUiLCJleHAiOjE1NzUxNjgxMzMsImlhdCI6MTU3NTA4MTczMywianRpIjoiMzY2MmRmMTgtZTQxMi00OWI3LTlmMGEtMGIyMzhkZWRkMzdiIn0.aIkw4IbiFSsAg4n9BvM-GSdu3Q1jiOyFjxvAW3dvhJY");
            System.out.println("id:"+c.getId());
            System.out.println("失效时间"+c.getExpiration());
            System.out.println("创建时间"+c.getIssuedAt());
            System.out.println(c.getSubject());
            System.out.println(c.getIssuer());
            System.out.println(c.get("id", String.class));
            System.out.println(c.get("title", String.class));
            System.out.println(c.get("nick_name", String.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出:

JWT:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIiLCJpc3MiOiJBbnNvbiIsImlkIjoiMSIsInRpdGxlIjoidGl0bGUiLCJleHAiOjE1NzUxNjgxNDgsImlhdCI6MTU3NTA4MTc0OCwianRpIjoiNzg1NTA4YmItMjkxMS00OTgwLTlkOGMtMDU2YTkzNmY1YjA2In0.V_z5yPd8U7Yvl3Z5eENH2V_QXHOld11_zGkDYuEfdgc
length:236
解密
id:3662df18-e412-49b7-9f0a-0b238dedd37b
失效时间Sun Dec 01 10:42:13 CST 2019
创建时间Sat Nov 30 10:42:13 CST 2019

Anson
1
title
null

 


评论区
请写下您的评论...
暂无评论...
猜你喜欢
工具 1888 全文检索流程分析图索引库中是如何存储的?数据库的一行数据会存储为一个document对象,一条录的一列会存储为一个field,不会将数据库的所有数据都存储到索引库。索引是如何创建过程流程图1.分析
分布式项目管理工具 1220 git&github学习使
工具 2301 javaweb图片验证码1.验证码的作:防止恶意破解密码、刷票、论坛灌水、刷页。有效防止某个黑客对某一个特定注册特定程序暴力破解方式进行不断的登录尝试,实际上使验证码是现在很多网站通行的方
前端(h5) 2095 打开,判断是否存储过户名---*/ varuName=window.localStorage.getItem('userName'); varpassword=window.localSt
activemq 1081 ActiveMQ
算法基础 3736 /dependency dependency groupIdcn.afterturn/groupId artifactIdeasypoi-web/artifactId version4.0.0/ver
框架 8223 上次我们说了spring集成websocket,实现websocket通讯集成配置连接:http://www.jiajiajia.club/weblog/blog/artical/128下面来模拟
算法基础 1410 c#对象和json字符串转换usingSystem; usingSystem.Runtime.Serialization.Json; usingSystem.IO; usingSystem.Text
归档
2018-11  12 2018-12  33 2019-01  28 2019-02  28 2019-03  32 2019-04  27 2019-05  33 2019-06  6 2019-07  12 2019-08  12 2019-09  21 2019-10  8 2019-11  15 2019-12  25 2020-01  9 2020-02  5 2020-03  16 2020-04  4 2020-06  1 2020-07  7 2020-08  13 2020-09  9 2020-10  5 2020-12  3 2021-01  1 2021-02  5 2021-03  7 2021-04  4 2021-05  4 2021-06  1 2021-07  7 2021-08  2 2021-09  8 2021-10  9 2021-11  16 2021-12  14 2022-01  7 2022-05  1 2022-08  3 2022-09  2 2022-10  2 2022-12  5 2023-01  3 2023-02  1 2023-03  4 2023-04  2 2023-06  3 2023-07  4 2023-08  1 2023-10  1 2024-02  1 2024-03  1 2024-04  1 2024-08  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy srs 音视频 webrtc javascript 加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。