JWT 和 JJWT,別再傻傻分不清了!
點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)
jwt是什么?
JWTs是JSON對(duì)象的編碼表示。JSON對(duì)象由零或多個(gè)名稱/值對(duì)組成,其中名稱為字符串,值為任意JSON值。
JWT有助于在clear(例如在URL中)發(fā)送這樣的信息,可以被信任為不可讀(即加密的)、不可修改的(即簽名)和URL - safe(即Base64編碼的)。
jwt的組成
Header: 標(biāo)題包含了令牌的元數(shù)據(jù),并且在最小包含簽名和/或加密算法的類型 Claims: Claims包含您想要簽署的任何信息 JSON Web Signature (JWS): 在header中指定的使用該算法的數(shù)字簽名和聲明
例如:
Header:
{
??"alg":?"HS256",
??"typ":?"JWT"
}
Claims:
{
??"sub":?"1234567890",
??"name":?"John?Doe",
??"admin":?true
}
Signature:
base64UrlEncode(Header)?+?"."?+?base64UrlEncode(Claims),
加密生成的token:

如何保證 JWT 安全
有很多庫可以幫助您創(chuàng)建和驗(yàn)證JWT,但是當(dāng)使用JWT時(shí),仍然可以做一些事情來限制您的安全風(fēng)險(xiǎn)。在您信任JWT中的任何信息之前,請(qǐng)始終驗(yàn)證簽名。這應(yīng)該是給定的。
換句話說,如果您正在傳遞一個(gè)秘密簽名密鑰到驗(yàn)證簽名的方法,并且簽名算法被設(shè)置為“none”,那么它應(yīng)該失敗驗(yàn)證。
確保簽名的秘密簽名,用于計(jì)算和驗(yàn)證簽名。秘密簽名密鑰只能由發(fā)行者和消費(fèi)者訪問,不能在這兩方之外訪問。
不要在JWT中包含任何敏感數(shù)據(jù)。這些令牌通常是用來防止操作(未加密)的,因此索賠中的數(shù)據(jù)可以很容易地解碼和讀取。
如果您擔(dān)心重播攻擊,包括一個(gè)nonce(jti索賠)、過期時(shí)間(exp索賠)和創(chuàng)建時(shí)間(iat索賠)。這些在JWT規(guī)范中定義得很好。

jwt的框架:JJWT
JJWT的目標(biāo)是最容易使用和理解用于在JVM上創(chuàng)建和驗(yàn)證JSON Web令牌(JWTs)的庫。 JJWT是基于JWT、JWS、JWE、JWK和JWA RFC規(guī)范的Java實(shí)現(xiàn)。 JJWT還添加了一些不屬于規(guī)范的便利擴(kuò)展,比如JWT壓縮和索賠強(qiáng)制。
規(guī)范兼容:
創(chuàng)建和解析明文壓縮JWTs 創(chuàng)建、解析和驗(yàn)證所有標(biāo)準(zhǔn)JWS算法的數(shù)字簽名緊湊JWTs(又稱JWSs): HS256: HMAC using SHA-256 HS384: HMAC using SHA-384 HS512: HMAC using SHA-512 RS256: RSASSA-PKCS-v1_5 using SHA-256 RS384: RSASSA-PKCS-v1_5 using SHA-384 RS512: RSASSA-PKCS-v1_5 using SHA-512 PS256: RSASSA-PSS using SHA-256 and MGF1 with SHA-256 PS384: RSASSA-PSS using SHA-384 and MGF1 with SHA-384 PS512: RSASSA-PSS using SHA-512 and MGF1 with SHA-512 ES256: ECDSA using P-256 and SHA-256 ES384: ECDSA using P-384 and SHA-384 ES512: ECDSA using P-521 and SHA-512
這里以github上的demo演示,理解原理,集成到自己項(xiàng)目中即可。Spring Boot 基礎(chǔ)就不介紹了,推薦下這個(gè)實(shí)戰(zhàn)教程:https://www.javastack.cn/categories/Spring-Boot/
應(yīng)用采用 spring boot + angular + jwt
結(jié)構(gòu)圖

"http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd">
????4.0.0
????com.nibado.example
????jwt-angular-spring
????0.0.2-SNAPSHOT
????
????????1.8
????????1.8
????????2.4
????????0.6.0
????????4.12
????????1.5.3.RELEASE
????
????
????????
????????????
????????????????org.springframework.boot
????????????????spring-boot-maven-plugin
????????????????${spring.boot.version}
????????????????
????????????????????
????????????????????????
????????????????????????????repackage
????????????????????????
????????????????????
????????????????
????????????
????????
????
????
????????
????????????org.springframework.boot
????????????spring-boot-starter-web
????????????${spring.boot.version}
????????
????????
????????????commons-io
????????????commons-io
????????????${commons.io.version}
????????
????????
????????????io.jsonwebtoken
????????????jjwt
????????????${jjwt.version}
????????
????????
????????????junit
????????????junit
????????????${junit.version}
????????
????
package?com.nibado.example.jwtangspr;
import?org.springframework.boot.SpringApplication;
import?org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import?org.springframework.boot.web.servlet.FilterRegistrationBean;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.ComponentScan;
import?org.springframework.context.annotation.Configuration;
@EnableAutoConfiguration
@ComponentScan
@Configuration
public?class?WebApplication?{
?
????//過濾器
????@Bean
????public?FilterRegistrationBean?jwtFilter()?{
????????final?FilterRegistrationBean?registrationBean?=?new?FilterRegistrationBean();
????????registrationBean.setFilter(new?JwtFilter());
????????registrationBean.addUrlPatterns("/api/*");
????????return?registrationBean;
????}
????public?static?void?main(final?String[]?args)?throws?Exception?{
????????SpringApplication.run(WebApplication.class,?args);
????}
}

