Java JWT实现跨域身份验证方法详解

目录
  • 1、JWT简介
  • 2、JWT的结构
    • 2.1 头部(header)
    • 2.2 载荷(payload)
    • 2.3 签证(signature)
  • 3、JWT的原则
  • 4、JWT的用法
  • 5、JWT的问题和趋势
  • 6、整合JWT令牌
    • 6.1 在模块中添加jwt工具依赖
    • 6.2 创建JWT工具类

1、JWT简介

JWT(JSON Web Token)是目前流行的跨域认证解决方案,是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

2、JWT的结构

JWT是由头部(header)、载荷(payload)、签证(signature)三段信息构成的,将三段信息文本用"."连接在一起就构成了JWT字符串。

例如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

使用在线校验工具(https://jwt.io/)将上述Token进行解码就可以看到数据,如下图所示

2.1 头部(header)

JWT的头部承载两部分信息:

(1)声明类型:这里主要是JWT。

(2)声明加密算法:通常直接使用HMAC SHA256。

例如:

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

alg属性表示签名所使用的算法;

JWT签名默认的算法为HMAC SHA256;

alg属性值HS256就是HMAC SHA256算法;

type属性表示令牌类型,这里是JWT。

2.2 载荷(payload)

载荷是JWT的主体,同样也是一个JSON对象。载荷包含三个部分:

(1)标准中的声明(Registered Claims):一组预定义的声明,不是强制的,但是推荐。

  • iss(issuer):JWT签发者
  • sub(subject):JWT索所面向的用户
  • aud(audience):接收JWT的一方
  • exp(expiration):JWT的过期时间,必须要大于签发时间。
  • nbf(not before):定义了再什么时间之前该JWT都是不可用的。
  • iat(issued at):JWT的发布时间,UNIX时间戳。
  • jti(JWT ID):JWT的唯一ID编号。

(2)公共的声明:可以添加任意信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息。

(3)私有的声明:提供者和消费者所共同定义的声明,一般不建议存放敏感信息。

2.3 签证(signature)

JWT的第三部分是一个签证信息,由三部分组成:header(base64后的)、payload(base64后的)、secret(密钥,需要保存好)。

例如:

HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

签名用于验证消息再传递过程中有没有被更改,并且对于使用私钥签名的Token还可以验证JWT的发送方是否为它所说的发送方。

secret是保存在服务端的,JWT的签发生成也是在服务端的,secret就是用来进行JWT的签发和验证的,所以secret是服务端的私钥,在任何场景都不应该流露出去。

3、JWT的原则

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

{
  "sub": "1234567890",
  "name": "Helen",
  "admin": true
}

之后,当用户与服务器通信时,客户在请求中发回JSON对象。服务器仅依赖于这个JSON对象来标识用户。为了防止用户篡改数据,服务器将在生成对象时添加签名。

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

4、JWT的用法

客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中。

此后,客户端将在与服务器交互中都会带JWT。如果将它存储在Cookie中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。当跨域时,也可以将JWT被放置于POST请求的数据主体中。

5、JWT的问题和趋势

JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数。

生产的token可以包含基本信息,比如id、用户昵称、头像等信息,避免再次查库

存储在客户端,不占用服务端的内存资源

JWT默认不加密,但可以加密。生成原始令牌后,可以再次对其进行加密。

当JWT未加密时,一些私密数据无法通过JWT传输。

JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。

JWT本身包含认证信息,token是经过base64编码,所以可以解码,因此token加密前的对象不应该包含敏感信息,一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行进行身份验证。

为了减少盗用和窃取,JWT不建议使用HTTP协议来传输代码,而是使用加密的HTTPS协议进行传输。

6、整合JWT令牌

6.1 在模块中添加jwt工具依赖

<dependencies>
    <!-- JWT-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>
</dependencies>

6.2 创建JWT工具类

/**
 * JWT工具类
 */
public class JwtHelper {
    //过期时间
    private static long tokenExpiration = 24*60*60*1000;
    //token签名密钥
    private static String tokenSignKey = "123456";

    //根据参数生成token
    public static String createToken(Long userId, String userName) {
        String token = Jwts.builder()
                .setSubject("YYGH-USER")
                //设置过期时间 30分钟
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                //设置主题信息  用户id和用户名称
                .claim("userId", userId)
                .claim("userName", userName)
                //签名哈希
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
        return token;
    }
    //根据token字符串得到用户id
    public static Long getUserId(String token) {
        if(StringUtils.isEmpty(token)) return null;
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        Integer userId = (Integer)claims.get("userId");
        return userId.longValue();
    }
    //根据token字符串得到用户名称
    public static String getUserName(String token) {
        if(StringUtils.isEmpty(token)) return "";
        Jws<Claims> claimsJws
            = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        return (String)claims.get("userName");
    }

}

写个主函数测试下:

public static void main(String[] args) {
        String token = JwtHelper.createToken(1L, "lucy");
        System.out.println(token);
        System.out.println(JwtHelper.getUserId(token));
        System.out.println(JwtHelper.getUserName(token));
    }

签发和解析都没问题。

到此这篇关于Java JWT实现跨域身份验证方法详解的文章就介绍到这了,更多相关JWT跨域身份验证内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于Token的身份验证之JWT基础教程

    前言 初次了解JWT,很基础,高手勿喷. 基于Token的身份验证用来替代传统的cookie+session身份验证方法中的session. token应用流程为: 1.初次登录:用户初次登录,输入用户名密码. 2.密码验证:服务器从数据库取出用户名和密码进行验证. 3.生成JWT:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成JWT. 4.返还JWT:服务器的HTTP RESPONSE中将JWT返还. 5.带JWT的请求:以后客户端发起请求,HTTP REQUEST HEADER

  • asp.net core3.1cookie和jwt混合认证授权实现多种身份验证方案

    目录 认证授权 身份认证 授权 默认授权 选择授权 总结 开发了一个公司内部系统,使用asp.net core 3.1.在开发用户认证授权使用的是简单的cookie认证方式,然后开发好了要写几个接口给其它系统调用数据.并且只是几个简单的接口不准备再重新部署一个站点,所以就直接在MVC的项目里面加了一个API区域用来写接口.这时候因为是接口所以就不能用cookie方式进行认证,得加一个jwt认证,采用多种身份验证方案来进行认证授权. 认证授权 身份验证是确定用户身份的过程. 授权是确定用户是否有权

  • asp.net基于JWT的web api身份验证及跨域调用实践

    随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的做法有所不同,除了面临跨域提交cookie的烦人问题外,更重要的是,有些终端可能根本不支持cookie. Json Web Token(jwt)是一种不错的身份验证及授权方案,简单的说就是调用端调用api时,附带上一个由api端颁发的token,以此来验证调用者的授权信息. 但由于时间关系,不对jw

  • c#关于JWT跨域身份验证的实现代码

    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案.为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519), 该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景.JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息, 以便于从资源服务器获取资源,该token也可直接被用于认证,也可被加密. 一.JWT的组成 下面是JWT的一段示例,分为三个部分,分别是头部(header),载荷(payload)}和签

  • 如何使用会话Cookie和Java实现JWT身份验证

    HTTP是无状态协议,用于传输数据.它启用了客户端和服务器端>之间的通信.它最初是为了在Web浏览器和Web服务器之间建立连接而建立的.比如在网上购物,我们添加一些商品,例如.耳机到我们的购物车,然后,我们继续寻找其他项目,在此期间,我们希望在执行任何其他任务是存储购物车项目的状态且不丢失它们.这意味着我们希望在整个购物过程中记住我们的状态.由于HTTP是无状态协议,因此要克服问题,我们可以使用会话或者令牌 1.基于会话的身份验证 在JSON Web令牌出现之前,我们主要使用这种身份验证.在这种

  • Django中的JWT身份验证的实现

    1.认证与授权 1.验证:身份验证是验证个人或设备标识的过程.身份验证过程之一是登录过程.注册网站后,您的信息(ID,密码,名称,电子邮件等)将存储在其数据库中.之后,您无需创建帐户即可提供信息.相反,您只需要提供用户名和密码来验证您的身份,网站就会自动知道您正在访问. 2.授权:授权是用于确定用户特权或访问级别的安全机制.在许多社区网站上,只有上传帖子和管理员的人才能删除它.当其他人尝试删除帖子时,网站应该抛出错误(但是在许多情况下,他们甚至看不到删除按钮).因此,对于每个请求,用户都需要证明

  • Java JWT实现跨域身份验证方法详解

    目录 1.JWT简介 2.JWT的结构 2.1 头部(header) 2.2 载荷(payload) 2.3 签证(signature) 3.JWT的原则 4.JWT的用法 5.JWT的问题和趋势 6.整合JWT令牌 6.1 在模块中添加jwt工具依赖 6.2 创建JWT工具类 1.JWT简介 JWT(JSON Web Token)是目前流行的跨域认证解决方案,是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该信息可以被验证和信

  • Nginx解决前端访问资源跨域问题的方法详解

    被前端跨域问题折磨快2天后,终于用ngnx的方式解决了,所以在此总结下. 该篇只探讨如何用Ngnx解决跨域问题,对于原理不作讨论. 1.首先介绍Windows环境下Nignx的相关命令操作 nginx常用命令: 验证配置是否正确: nginx -t 查看Nginx的版本号:nginx -V 启动Nginx:start nginx 快速停止或关闭Nginx:nginx -s stop 正常停止或关闭Nginx:nginx -s quit 配置文件修改重装载命令:nginx -s reload 在停

  • C#设置或验证PDF文本域格式的方法详解

    目录 概述 引入dll 代码(C#/VB.NET) 概述 PDF中的文本域可以通过设置不同格式,用于显示数字.货币.日期.时间.邮政编码.电话号码和社保号等等.Adobe Acrobat提供了许多固定的JavaScripts用来设置和验证文本域的格式,如:AFNumber_Format(2, 0, 0, 0, "$", true)和AFNumber_Keystroke(2, 0, 0, 0, "$", true).Format后缀的script是用来设置文本域显示的

  • 面试突击之跨域问题的解决方案详解

    目录 1.跨域三种情况 2.跨域问题演示 2.1 前端网站 2.2 后端接口 3.解决跨域问题 3.1 通过注解跨域 3.2 通过配置文件跨域 3.3 通过 CorsFilter 跨域 3.4 通过 Response 跨域 3.5 通过 ResponseBodyAdvice 跨域 4.原理分析 演示项目源码 总结 跨域问题指的是不同站点之间,使用 ajax 无法相互调用的问题.跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据. 但这个保护机制也带来了新的问题

  • Java实现API sign签名校验的方法详解

    目录 1. 前言 2. 签名生成策略 3. API 签名算法 Java 实现 4. 测试一下 1. 前言 目的:为防止中间人攻击. 场景: 项目内部前后端调用,这种场景只需要做普通参数的签名校验和过期请求校验,目的是为了防止攻击者劫持请求 url 后非法请求接口. 开放平台向第三方应用提供能力,这种场景除了普通参数校验和请求过期校验外,还要考虑 3d 应用的授权机制,不被授权的应用就算传入了合法的参数也不能被允许请求成功. 2. 签名生成策略 接下来详述场景 2,其实场景 1 也包含在场景 2

  • Java利用StampedLock实现读写锁的方法详解

    目录 概述 StampedLock介绍 演示例子 性能对比 总结 概述 想到读写锁,大家第一时间想到的可能是ReentrantReadWriteLock.实际上,在jdk8以后,java提供了一个性能更优越的读写锁并发类StampedLock,该类的设计初衷是作为一个内部工具类,用于辅助开发其它线程安全组件,用得好,该类可以提升系统性能,用不好,容易产生死锁和其它莫名其妙的问题.本文主要和大家一起学习下StampedLock的功能和使用. StampedLock介绍 StampedLock的状态

  • Java 添加超链接到 Word 文档方法详解

    在Word文档中,超链接是指在特定文本或者图片中插入的能跳转到其他位置或网页的链接,它也是我们在编辑制作Word文档时广泛使用到的功能之一.今天这篇文章就将为大家演示如何使用Free Spire.Doc for Java在Word文档中添加文本超链接和图片超链接. Jar包导入 方法一:下载Free Spire.Doc for Java包并解压缩,然后将lib文件夹下的Spire.Doc.jar包作为依赖项导入到Java应用程序中. 方法二:通过Maven仓库安装JAR包,配置pom.xml文件

  • Java Fluent Mybatis 聚合查询与apply方法详解流程篇

    前言 接着上一篇文章:Java Fluent Mybatis 分页查询与sql日志输出详解流程篇 我把分页已经调整好了,现在实验一下官方给出的聚合查询方法. GitHub代码仓库:GitHub仓库 数据准备 为了聚合查询的条件,添加了几条数据. MIN 我们试着获取最小的年龄. 方法实现 @Override public Integer getAgeMin() { Map<String, Object> result = testFluentMybatisMapper .findOneMap(

  • Java实现字符串转为驼峰格式的方法详解

    字符串转为驼峰格式 构建工具类 package com.yt.common.util; import com.yt.common.dto.NameCode; import com.yt.exam.enums.ZyEnum; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 字符串转为驼峰格式 构建工具类 * @author LYY * @date 2022/07

随机推荐