JavaMVC框架Java技术分享Web前端

JWT(Json Web Token)

2020-06-01  本文已影响0人  Belmode

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。和 Cookie-Session 的模式不同,JSON Web Token(JWT)使用 Token 替换了 SessionId 的资源访问和状态的保持。基于JWT的Token认证的方式有很多优点,本文将介绍 JJWT 的相关用法。

jwt是什么?

JWTs是JSON对象的编码表示。JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值。JWT有助于在clear(例如在URL中)发送这样的信息,可以被信任为不可读(即加密的)、不可修改的(即签名)和URL – safe(即Base64编码的)。

jwt的组成

jwt 的认证过程

  1. 用户登录系统;
  2. 服务端验证,将认证信息通过指定的算法(例如HS256)进行加密,例如对用户名和用户所属角色进行加密,加密私钥是保存在服务器端的,将加密后的结果发送给客户端,加密的字符串格式为三个"." 分隔的字符串 Token,分别对应头部、载荷与签名,头部和载荷都可以通过 base64 解码出来,签名部分不可以;
  3. 客户端拿到返回的 Token,存储到 local storage 或本地数据库;
  4. 下次客户端再次发起请求,将 Token 附加到 header 中;
  5. 服务端获取 header 中的 Token ,通过相同的算法对 Token 中的用户名和所属角色进行相同的加密验证,如果验证结果相同,则说明这个请求是正常的,没有被篡改。这个过程可以完全不涉及到查询 Redis 或其他存储;

JWT 安全性

jwt的优点

JJWT

JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。

JJWT 规范兼容

下面我们根据 https://github.com/jwtk/jjwt 上的demo,来介绍下 JJWT 的用法。

jjwt 安装

jjwt 提供了 Maven 和 Gradle 两种构建方式,Maven 配置如下即可使用 JJWT。

<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt</artifactId>
  <version>0.9.0</version>
</dependency>

Gradle 使用方式如下:

dependencies {
compile 'io.jsonwebtoken:jjwt:0.9.0'
}

注意:JJWT依赖于Jackson 2.x. 如果您已经在您的应用程序中使用了旧版本的 Jackson 请升级相关配置。

创建签名密钥

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

import io.jsonwebtoken.impl.crypto.MacProvider;

import java.security.Key;

// 创建签名密钥,通常将从应用程序配置中读取。

// 业余草:www.xttblog.com

Key key = MacProvider.generateKey();

String compactJws = Jwts.builder()

  .setSubject("Joe")

  .signWith(SignatureAlgorithm.HS512, key)

  .compact();

验证JWT

assert Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws).getBody().getSubject().equals("Joe");

SignatureException 异常

签名验证失败呢?你可以捕捉SignatureException并作出相应的反应。

try {

    Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);

    //OK, we can trust this JWT

    //业余草:www.xttblog.com

} catch (SignatureException e) {

    //don't trust the JWT!

}

压缩签名

String compactJws =  Jwts.builder()
    .setSubject("Joe")
    .compressWith(CompressionCodecs.DEFLATE)
    .signWith(SignatureAlgorithm.HS512, key)
    .compact();

解析时,可以指定某些声明必须存在并设置为特定值。

try {

    Jws<Claims> claims = Jwts.parser()

        .requireSubject("Joe")

        .require("hasMotorcycle", true)

        .setSigningKey(key)

        .parseClaimsJws(compactJws);

} catch (MissingClaimException e) {

    // we get here if the required claim is not present

} catch (IncorrectClaimException e) {

    // we get here if the required claim has the wrong value

    //业余草:www.xttblog.com

}

参考资料

上一篇下一篇

猜你喜欢

热点阅读