jwt使用详细讲解

-JWT 实战教程

1.什么是jwt

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公用/专用密钥对对JWT进行签名。

通俗的解释
jwt 简称json web token 也就是通过json 形式作为web 应用中的令牌,用于在各方面之间安全的将信息作json 对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。

2.jwt 能做什么

•授权:这是使用JWT的最常见方案。用户登录后,每个后续请求都将包含JWT,从而允许该用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,这是因为它的开销很小并且易于在不同域中使用。
•信息交换:JSON Web令牌是在各方之间安全地传输信息的一种好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确保发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改

基于传统的Session登入

每次登入都会创建一个session,发送给客户端一个cookie保存对应sessionid,用来解决http无状态的基础上保存用户会话信息的问题。

基于session认证显露出来的问题:

性能:
每一个用户经过后端应用认证之后,后端应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大,与REST风格不匹配。因为它在一个无状态协议里注入了状态。

扩展性:
用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

网络安全:
CSRF(跨站伪造请求攻击)攻击:因为基于cookie来进行用户识别, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

跨平台:
在移动应用上 session 和 cookie 很难行通,你无法与移动终端共享服务器创建的 session 和 cookie。

基于jwt认证

2021-02-05 20.26.22.png"

JWT组成

x.y.z:
x:header ,y:payload ,z:signature . 使用Base64编码组成jwt三部分

先来看一张JWT的信息的截图:

img

从上图可以看到,JWT含有三部分:头部(header)、载荷(payload)、签名(signature)。

  1. 头部(header)

JWT的头部有两部分信息:

  • 声明类型(type),这里是JWT
  • 声明加密的算法(algorithm),通常直接使用HMAC SHA256 、RSA

头部示例如下:

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

头部一般使用base64加密,加密后密文:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

  1. 载荷(payload)

该部分一般存放一些有效的信息。JWT的标准定义包含五个字段:

  • iss:该JWT的签发者
  • sub: 该JWT所面向的用户
  • aud: 接收该JWT的一方
  • exp(expires): 什么时候过期,这里是一个Unix时间戳
  • iat(issued at): 在什么时候签发的

载荷示例如下:

{
  "sub": "1234567890",
  "name": "Java碎碎念",
  "iat": 1516239022
}
  1. 签名(signature)

前面两部分都是使用Base64进行编码的,即前端可以解开知道里面的信息。signature 需要使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的签名算法(HS256)进行签名。签名的作用是保证 JWT 没有被篡改过。因此在不知道密钥的话服务器加密得出来的签名也就是不一样的。(header+payload+secret).HS256=signature

三个部分通过.连接在一起就是我们的 JWT 了,所以我们生成的JWT如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphdmHnoo7noo7lv7UiLCJpYXQiOjE1MTYyMzkwMjJ9.LLJIkhJs6SVYlzn3n8fThQmhGutjTDI3RURTLtHV4ls

注意⚠️:payload中不要放密码等敏感信息,因为信息jwt被截取了使用Base64 decode 就可以把密码解出。

3.jwt使用

#1.引入依赖
<!--引入jwt-->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.4.0</version>
</dependency>
#2.生成token(encoded)
Calendar instance =Calendar.getInstance();
try {
   
    Algorithm algorithm = Algorithm.HMAC256("secret!!");//设置签名,保密复杂
    String token = JWT.create()
      	.withClaim("username","张三")//设置自定义用户名
      	.withExpiresAt(instance.getTime())//设置过期时间
        .withIssuer("auth0")  //指定发行人
        .sign(algorithm);
} catch (JWTCreationException exception){
   
    //Invalid Signing configuration / Couldn't convert Claims.
}
#3.解码token(decoded)
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
try {
   
    Algorithm algorithm = Algorithm.HMAC256("secret!!");
    JWTVerifier verifier = JWT.require(algorithm)
        .withIssuer
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值