当前位置:网站首页>OAuth2:使用JWT令牌
OAuth2:使用JWT令牌
2022-07-31 14:05:00 【Leon_Jinhai_Sun】
JSON Web Token令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑和自成一体的方式,用于在各方之间作为JSON对象安全地传输信息。这些信息可以被验证和信任,因为它是数字签名的。JWT可以使用密钥(使用HMAC算法)或使用RSA或ECDSA进行公钥/私钥对进行签名。
实际上,我们之前都是携带Token向资源服务器发起请求后,资源服务器由于不知道我们Token的用户信息,所以需要向验证服务器询问此Token的认证信息,这样才能得到Token代表的用户信息,但是各位是否考虑过,如果每次用户请求都去查询用户信息,那么在大量请求下,验证服务器的压力可能会非常的大。而使用JWT之后,Token中会直接保存用户信息,这样资源服务器就不再需要询问验证服务器,自行就可以完成解析,我们的目标是不联系验证服务器就能直接完成验证。
JWT令牌的格式如下:

一个JWT令牌由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终需要传输的字符串。
- 标头:包含一些元数据信息,比如JWT签名所使用的加密算法,还有类型,这里统一都是JWT。
- 有效载荷:包括用户名称、令牌发布时间、过期时间、JWT ID等,当然我们也可以自定义添加字段,我们的用户信息一般都在这里存放。
- 签名:首先需要指定一个密钥,该密钥仅仅保存在服务器中,保证不能让其他用户知道。然后使用Header中指定的算法对Header和Payload进行base64加密之后的结果通过密钥计算哈希值,然后就得出一个签名哈希。这个会用于之后验证内容是否被篡改。
这里还是补充一下一些概念,因为很多东西都是我们之前没有接触过的:
- Base64:就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"一共64个字符的字符集(末尾还有1个或多个
=用来凑够字节数),任何的符号都可以转换成这个字符集中的字符,这个转换过程就叫做Base64编码,编码之后会生成只包含上述64个字符的字符串。相反,如果需要原本的内容,我们也可以进行Base64解码,回到原有的样子。
public void test(){
String str = "你们可能不知道只用20万赢到578万是什么概念";
//Base64不只是可以对字符串进行编码,任何byte[]数据都可以,编码结果可以是byte[],也可以是字符串
String encodeStr = Base64.getEncoder().encodeToString(str.getBytes());
System.out.println("Base64编码后的字符串:"+encodeStr);
System.out.println("解码后的字符串:"+new String(Base64.getDecoder().decode(encodeStr)));
}
注意Base64不是加密算法,只是一种信息的编码方式而已。
- 加密算法:加密算法分为对称加密和非对称加密,其中对称加密(Symmetric Cryptography)比较好理解,就像一把锁配了两把钥匙一样,这两把钥匙你和别人都有一把,然后你们直接传递数据,都会把数据用锁给锁上,就算传递的途中有人把数据窃取了,也没办法解密,因为钥匙只有你和对方有,没有钥匙无法进行解密,但是这样有个问题,既然解密的关键在于钥匙本身,那么如果有人不仅窃取了数据,而且对方那边的治安也不好,于是顺手就偷走了钥匙,那你们之间发的数据不就凉凉了吗。
因此,非对称加密(Asymmetric Cryptography)算法出现了,它并不是直接生成一把钥匙,而是生成一个公钥和一个私钥,私钥只能由你保管,而公钥交给对方或是你要发送的任何人都行,现在你需要把数据传给对方,那么就需要使用私钥进行加密,但是,这个数据只能使用对应的公钥进行解密,相反,如果对方需要给你发送数据,那么就需要用公钥进行加密,而数据只能使用私钥进行解密,这样的话就算对方的公钥被窃取,那么别人发给你的数据也没办法解密出来,因为需要私钥才能解密,而只有你才有私钥。
因此,非对称加密的安全性会更高一些,包括HTTPS的隐私信息正是使用非对称加密来保障传输数据的安全(当然HTTPS并不是单纯地使用非对称加密完成的,感兴趣的可以去了解一下)
对称加密和非对称加密都有很多的算法,比如对称加密,就有:DES、IDEA、RC2,非对称加密有:RSA、DAS、ECC
- 不可逆加密算法:常见的不可逆加密算法有MD5, HMAC, SHA-1, SHA-224, SHA-256, SHA-384, 和SHA-512, 其中SHA-224、SHA-256、SHA-384,和SHA-512我们可以统称为SHA2加密算法,SHA加密算法的安全性要比MD5更高,而SHA2加密算法比SHA1的要高,其中SHA后面的数字表示的是加密后的字符串长度,SHA1默认会产生一个160位的信息摘要。经过不可逆加密算法得到的加密结果,是无法解密回去的,也就是说加密出来是什么就是什么了。本质上,其就是一种哈希函数,用于对一段信息产生摘要,以防止被篡改。
实际上这种算法就常常被用作信息摘要计算,同样的数据通过同样的算法计算得到的结果肯定也一样,而如果数据被修改,那么计算的结果肯定就不一样了。
这里我们就可以利用jwt,将我们的Token采用新的方式进行存储:

这里我们使用最简单的一种方式,对称密钥,我们需要对验证服务器进行一些修改:
@Bean
public JwtAccessTokenConverter tokenConverter(){ //Token转换器,将其转换为JWT
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("lbwnb"); //这个是对称密钥,一会资源服务器那边也要指定为这个
return converter;
}
@Bean
public TokenStore tokenStore(JwtAccessTokenConverter converter){ //Token存储方式现在改为JWT存储
return new JwtTokenStore(converter); //传入刚刚定义好的转换器
}@Resource
TokenStore store;
@Resource
JwtAccessTokenConverter converter;
private AuthorizationServerTokenServices serverTokenServices(){ //这里对AuthorizationServerTokenServices进行一下配置
DefaultTokenServices services = new DefaultTokenServices();
services.setSupportRefreshToken(true); //允许Token刷新
services.setTokenStore(store); //添加刚刚的TokenStore
services.setTokenEnhancer(converter); //添加Token增强,其实就是JwtAccessTokenConverter,增强是添加一些自定义的数据到JWT中
return services;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.tokenServices(serverTokenServices()) //设定为刚刚配置好的AuthorizationServerTokenServices
.userDetailsService(service)
.authenticationManager(manager);
}然后我们就可以重启验证服务器了:

可以看到成功获取了AccessToken,但是这里的格式跟我们之前的格式就大不相同了,因为现在它是JWT令牌,我们可以对其进行一下Base64解码:

可以看到所有的验证信息包含在内,现在我们对资源服务器进行配置:
security:
oauth2:
resource:
jwt:
key-value: lbwnb #注意这里要跟验证服务器的密钥一致,这样算出来的签名才会一致然后启动资源服务器,请求一下接口试试看:

请求成功,得到数据:

注意如果Token有误,那么会得到:

边栏推荐
- Usage of += in C#
- el-tooltip的使用
- 页面整屏滚动效果
- Redis 】 【 publish and subscribe message
- mysql8, starttime的下一个值作为endtime的上一个值?
- hyperf的启动源码分析(二)——请求如何到达控制器
- Install the latest pytorch gpu version
- Analysis of the startup source code of hyperf (2) - how the request reaches the controller
- 已解决(pymysqL连接数据库报错)pymysqL.err.ProgrammingError: (1146,“Table ‘test.students‘ doesn‘t exist“)
- A detailed explanation of the usage of Async and Await in C#
猜你喜欢

Shang Silicon Valley-JVM-Memory and Garbage Collection (P1~P203)

All-round visual monitoring of the Istio microservice governance grid (microservice architecture display, resource monitoring, traffic monitoring, link monitoring)

Node version switching management using NVM

【redis】发布和订阅消息

Even if the image is missing in a large area, it can also be repaired realistically. The new model CM-GAN takes into account the global structure and texture details

ADS communicate with c #

In the future, the interviewer asks you why it is not recommended to use Select *, please answer him out loud!

The recently popular domestic interface artifact Apipost experience

「面经分享」西北大学 | 字节 生活服务 | 一面二面三面 HR 面

纸质说明书秒变3D动画,斯坦福大学吴佳俊最新研究,入选ECCV 2022
随机推荐
Numbers that appear only once in LeetCode
C# Get network card information NetworkInterface IPInterfaceProperties
Usage of += in C#
Redis 】 【 publish and subscribe message
Save and load numpy matrices and vectors, and use the saved vectors for similarity calculation
Motion capture system for end-positioning control of flexible manipulators
技能大赛训练题:交换机虚拟化练习
CodeIgniter 打开错误日志
Batch大小不一定是2的n次幂!ML资深学者最新结论
Detailed guide to compare two tables using natural full join in SQL
Use of C# Assembly
【Pytorch】torch.argmax()用法
The pre-sale of the new Hyundai Paristi is open, and safety and comfort are not lost
hyperf的启动源码分析(二)——请求如何到达控制器
SetoolKit使用指南
Resnet&API
五个维度着手MySQL的优化
endnote引用
对数字化时代的企业来说,数据治理难做,但应该去做
技能大赛训练题:ftp 服务攻防与加固