关于java:JWT学习笔记一

6次阅读

共计 5778 个字符,预计需要花费 15 分钟才能阅读完成。

这周在做单点登录,这次的单点登录解析用户信息是 JWT 中解析用户信息,然而第三方给的从 JWT 中解析用户信息的文档中提供解析 token 的形式解不进去,我过后心态就有点崩,起初本人查了一些材料才发现第三方给的从 JWT 中解析用户信息的形式是有问题的,然而我一想还是对 JWT 还不大理解,于是打算零碎的学一下 JWT。

JWT 概览

是什么?

我个别学习新技术都很喜爱官网文档做的简洁明了的,JWT 就是,JWT 的官网就做的非常好, 第一眼你想晓得的就摆在了你的眼前:
JWT 是 JSON(不懂什么是 JSON 的能够翻翻我之前写的文章: 傻傻弄不分明的 JSON?) WEB Token(令牌)的缩写,所以按字面意思咱们就能够将 JWT 了解为 WEB 中 JSON 模式的令牌,这个令牌你能够了解为通行证,进入零碎的令牌。

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.

JWT 是一种被凋谢标准 RFC-7519 所定义的一种在不同平安实体应用 JSON 平安传输数据的一种 (紧凑而又自蕴含) 办法(或者形式)。

his 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.

因为 JWT 带有数字签名,所以应用 JWT 传输的信息是能够验证和信赖的。电子签名能够应用 HMAC 算法或者应用 RSA、ECDSA 非对称加密的公钥、私钥来实现。

Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.
只管 JWT 因为被加密从而为两个平安实体之间替换信息提供安全性,咱们还是将注意力放在被签名的 token 上。领有签名的 token(或者被签名的 token)能够验证蕴含在其中的信息的完整性。加密过的 token 也暗藏了起源方的信息。当令牌所应用的签名形式持有公钥或者私钥时,签名也能够证实持有私钥的是对 token 进行签名的那一方。

RFC 是什么?

RFC 是 Request for Comments 的缩写,翻译的话能够了解为征求意见稿,互联网存在一系列的规范和协定,比方 HTTP、TCP 等,那这些协定和规范由谁来推动或者更新呢?就是由互联网工程工作组 (IETF) 来推动和更新的,RFC 就像是一份征求意见稿一样,每份网络协议的更新都会有对应的 RFC,由 IETF 审核通过之后,予以推广。1996 年 3 月,清华大学提交的适应不同国家和地区中文编码的汉字对立传输规范被 IETF 通过为 RFC 1922,成为中国大陆第一个被认可为 RFC 文件的提交协定。

能够用来干什么?

  • Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token. Single Sign On is a feature that widely uses JWT nowadays, because of its small overhead and its ability to be easily used across different domains.

    鉴权: 这是 JWT 最常见的应用场景,只有用户一次胜利登陆,之后的每次申请携带 JWT,就可能拜访这个 JWT 所被容许的拜访的所有(咱们能够了解为 JWT 是一个相似于身份证的存在,服务端从申请中拿到 JWT 就可能晓得以后登录用户是谁以及所容许的拜访的资源)。当今,单点登录宽泛应用 JWT 实现,因为开销小,并且可能在很容易不同的平安实体中所应用。

  • Information Exchange: JSON Web Tokens are a good way of securely transmitting information between parties. Because JWTs can be signed—for example, using public/private key pairs—you can be sure the senders are who they say they are. Additionally, as the signature is calculated using the header and the payload, you can also verify that the content hasn’t been tampered with.

信息替换:JWT 是一个在不同实体中平安替换信息的良好实现,因为 JWT 的签名,比方应用非对称加密,你就能够确信发送者的身份(避免第三方混充),签名是通过 JWT 的 header 和 payload 计算得来。你能够通过这个来验证这些信息有没有被批改过

JWT 的组成

header

这个 payload 咱们权且能够了解为申请体,携带所要了所要替换的信息,header 携带的信息为加密形式,自身也用 Base64URL 进行加密。JWT 的三局部之间由. 来进行宰割,典型的 JWT 组成像上面这样:

xxxxx.yyyyy.zzzzz

典型的 header 组成:

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

claims

The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.
Payload 中携带了替换的信息,这些替换的信息在申明中,替换的信息个别是实体 (典型的就是用户) 和一些额定的数据,有三种类型的申明:

  • Registered claims(曾经定义过的申明): These are a set of predefined claims which are not mandatory but recommended, to provide a set of useful, interoperable claims. Some of them are: iss (issuer), exp (expiration time), sub (subject), aud (audience), and others.

    这些申明是预约义字段是非强制然而举荐的,用于提供一组无效的申明。一些典型的,比方 iss(发行者)、exp(过期工夫)、sub(Subject 主体)等等,为什么都是缩写?因为 JWT 要求紧凑。

  • Public claims

    These can be defined at will by those using JWTs. But to avoid collisions they should be defined in the IANA JSON Web Token Registry or be defined as a URI that contains a collision resistant namespace.
    这些能够由应用 JWTs 的人自定义,然而为了防止抵触,在定义之后在 IANA JSON Web Token Registry 注册一下,或者在被定义在 URI 能够防止抵触。

  • Private claims:

    These are the custom claims created to share information between parties that agree on using them and are neither registered or public claims.
    这是信息替换单方对立替换信息的申明,不该当被注册或者公布在公共申明外面。
    咱们能够将申明了解为字段,Registered claims 了解为预约义字段,Public claims 了解为大家约定的字段。Payload 也用 Base64 进行加密。

Do note that for signed tokens this information, though protected against tampering, is readable by anyone. Do not put secret information in the payload or header elements of a JWT unless it is encrypted.
如果信息没有被加密,那么不倡议在 payload 中放入机密信息,只管这些信息能够被签名爱护,不被篡改,但任何人都能够浏览到。
payload 示例:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

signature

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that .For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:
创立签名局部你须要将 header 和 payload、secret 依照申请头中的加密算法进行编码。上面是一个应用 HMAC SHA256 算法创立签名的典型例子:

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

The signature is used to verify the message wasn’t changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.

这个签名的作用是验证信息在传输过程中有没有被改过,在应用私钥签名的状况下,咱们能够验证发送者的身份。

怎么用?

咱们当初来尝试应用一下 JWT,首先咱们去 maven 私服,去找下对应 jar 包:

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.1</version>
</dependency>

生成 JWT 并解析 JWT

public class Test {public static void main(String[] args) {String  str = makeToken();
        parseToken(str);
    }

    private static void parseToken(String str) {
        // 放入签发的密钥,对 JWT 进行解密
        Jwt info = Jwts.parser().setSigningKey("changanbujian").parse(str);
        System.out.println(info);
    }

    private static String makeToken() {Map<String,Object> header = new HashMap<>();
        header.put("alg","HS256");
        header.put("typ","JWT");
        Claims claims = new DefaultClaims();
        claims.setId("ccc").setSubject("aaa").setIssuer("bbb").setExpiration(new Date(System.currentTimeMillis() + 1800 * 1000));
        String secret = "changanbujian";
        // 下面讲过 JWT 须要 Base64 的模式
        byte[] saltBase64 = DatatypeConverter.parseBase64Binary(secret);
        SignatureAlgorithm hs256 = SignatureAlgorithm.HS256;
        SecretKeySpec secretKeySpec = new SecretKeySpec(saltBase64,hs256.getJcaName());
        String jwtToken = Jwts.builder().setHeader(header).setClaims(claims).signWith(hs256, secretKeySpec).compact();
        return jwtToken;
    }
}

总结一下

JWT 是 JSON WEB TOKEN 的缩写,是令牌的一种模式,有三局部组成:

  • header

    携带加密算法

  • payload

    携带信息

  • signature

    依据 header 和 payload 生成,避免被篡改,也确认发送者的身份。

理论应用中咱们经常会对在原来的 JWT 的根底上再进行加密,加密和解密形式对的上,能力从密文中解析进去信息。

参考资料

  • JWT 文档翻译中英对照 — introduction
  • JWT 官网
正文完
 0