热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JWT相关介绍

JWT(JsonWebToken)好,今天我们来学JWTJWT简介JWT英文名是JsonWebToken,是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范,经

JWT(Json Web Token)

好,今天我们来学JWT

JWT简介

JWT 英文名是 Json Web Token ,是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范,经常用在跨域身份验证。JWT 以 JSON 对象的形式安全传递信息。因为存在数字签名,因此所传递的信息是安全的。

为什么我们要学习这个JWT呢?

我们从简介中可以知道

“JWT一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范”

所以这个东西可以用来跟踪会话。我们知道http协议是无状态的,应用jwt,我们可以完成基于token的登陆验证功能。(而不是使用传统的COOKIE和session)顺便可以完成实践作业中所需要的功能

HTTP协议

既然聊到会话跟踪,我们追根溯源,来了解一下http协议。

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。

HTTP工作原理

HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
客户端通过发送请求(request)到服务器中,服务器通过响应(response)来反馈客户端的请求

HTTP注意事项

HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

JWT相关介绍

我们不过多分析http的深层次内容,现在我们回到jwt上面来。

我们这里抛出一个问题:

用户验证过程:

  1. 用户向服务器发送用户名和密码。
  2. 验证服务器后,相关数据(如用户角色,登录时间等)将保存在当前会话中。
  3. 服务器向用户返回session_id,session信息都会写入到用户的COOKIE。
  4. 用户的每个后续请求都将通过在COOKIE中取出session_id传给服务器。
  5. 服务器收到session_id并对比之前保存的数据,确认用户的身份。
    如图所示:
    JWT相关介绍

这种模式最大的问题是,没有分布式架构,无法支持横向扩展。如果使用一个服务器,该模式完全没有问题。但是,如果它是服务器群集或面向服务的跨域体系结构的话,则需要一个统一的session数据库库来保存会话数据实现共享,这样负载均衡下的每个服务器才可以正确的验证用户身份。

jwt原则

JWT的原则是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户,如下所示。

{

"UserName": "zc990306",

"Role": "Admin",

"token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

}

服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展。

jwt的数据结构

JWT头、有效载荷和签名

JWT相关介绍

我们着重介绍一下签名哈希

签名哈希部分是对前面两部分(jwt头,有效载荷)数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。
首先,需要指定一个密码(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为HMAC SHA256),在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用"."分隔,就构成整个JWT对象。

jwt的用法

客户端接收服务器返回的JWT,将其存储在COOKIE或localStorage中。
此后,客户端将在与服务器交互中都会带JWT。如果将它存储在COOKIE中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。


下面我们直接贴代码

public class TokenUtil {
    private static final long EXPIRE_TIME= 10*60*60*1000;
    private static final String TOKEN_SECRET="txdy";  //密钥盐

    public static String sign(String username){
        String token = null;
        try {
            Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            token = JWT.create()
                    .withIssuer("auth0")
                    .withClaim("username", username)
                    .withExpiresAt(expiresAt)
                    // 使用了HMAC256加密算法。
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (Exception e){
            e.printStackTrace();
        }
        return token;
    }

    public static boolean verify(String token){
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
            DecodedJWT jwt = verifier.verify(token);
            System.out.println("认证通过:");
            System.out.println("username: " + jwt.getClaim("username").asString());
            System.out.println("过期时间:      " + jwt.getExpiresAt());
            return true;
        } catch (Exception e){
            return false;
        }
    }

    public static String getUsername(String token){
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getClaim("username").asString();
    }
}

当时在使用这段代码时,由于是依靠后端重新计算一遍token来进行验证的,但是在测试时发现,对同一个账号在不同时间计算出的token不同,因此verify进行验证的时候炸了好几次。由于不了解HMAC256算法,只能重新添加一个getUsername方法去直接通过jwt来获得解析过的数据。

总结

对于jwt,java官网已经有了相应的工具类的实现,我们只需要根据自身项目的需要进行封装即可。

参考文献

一文读懂JWT
jwt介绍
十分钟了解web令牌
http教程
《图解HTTP》(人民邮电出版社)


推荐阅读
  • 本文详细介绍了Java代码分层的基本概念和常见分层模式,特别是MVC模式。同时探讨了不同项目需求下的分层策略,帮助读者更好地理解和应用Java分层思想。 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • 小程序的授权和登陆
    小程序的授权和登陆 ... [详细]
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 本文介绍了 Go 语言中的高性能、可扩展、轻量级 Web 框架 Echo。Echo 框架简单易用,仅需几行代码即可启动一个高性能 HTTP 服务。 ... [详细]
  • 微服务优雅上下线的最佳实践
    本文介绍了微服务上下线的正确姿势,避免使用 kill -9 等粗暴手段,确保服务的稳定性和可靠性。 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 包含phppdoerrorcode的词条 ... [详细]
  • 高端存储技术演进与趋势
    本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ... [详细]
  • 本文详细介绍了如何在PHP中记录和管理行为日志,包括ThinkPHP框架中的日志记录方法、日志的用途、实现原理以及相关配置。 ... [详细]
  • 应用链时代,详解 Avalanche 与 Cosmos 的差异 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 本文详细介绍了如何解决DNS服务器配置转发无法解析的问题,包括编辑主配置文件和重启域名服务的具体步骤。 ... [详细]
author-avatar
月在杏花枝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有