文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java JWT如何实现跨域身份验证

2023-06-26 03:49

关注

今天小编给大家分享一下Java 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进行解码就可以看到数据,如下图所示

Java JWT如何实现跨域身份验证

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):一组预定义的声明,不是强制的,但是推荐。

(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工具类

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如何实现跨域身份验证

签发和解析都没问题。

以上就是“Java JWT如何实现跨域身份验证”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯