日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

golang jwt设置过期_听说你的JWT库用起来特别扭,推荐这款贼好用的!

發布時間:2023/12/1 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang jwt设置过期_听说你的JWT库用起来特别扭,推荐这款贼好用的! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以前一直使用的是jjwt這個JWT庫,雖然小巧夠用, 但對JWT的一些細節封裝的不是很好。最近發現了一個更好用的JWT庫nimbus-jose-jwt,簡單易用,API非常易于理解,對稱加密和非對稱加密算法都支持,推薦給大家!

簡介

nimbus-jose-jwt是最受歡迎的JWT開源庫,基于Apache 2.0開源協議,支持所有標準的簽名(JWS)和加密(JWE)算法。

JWT概念關系

這里我們需要了解下JWT、JWS、JWE三者之間的關系,其實JWT(JSON Web Token)指的是一種規范,這種規范允許我們使用JWT在兩個組織之間傳遞安全可靠的信息。而JWS(JSON Web Signature)和JWE(JSON Web Encryption)是JWT規范的兩種不同實現,我們平時最常使用的實現就是JWS。

使用

接下來我們將介紹下nimbus-jose-jwt庫的使用,主要使用對稱加密(HMAC)和非對稱加密(RSA)兩種算法來生成和解析JWT令牌。

對稱加密(HMAC)

對稱加密指的是使用相同的秘鑰來進行加密和解密,如果你的秘鑰不想暴露給解密方,考慮使用非對稱加密。

  • 要使用nimbus-jose-jwt庫,首先在pom.xml添加相關依賴;

<dependency>
????<groupId>com.nimbusdsgroupId>
????<artifactId>nimbus-jose-jwtartifactId>
????<version>8.16version>
dependency>
  • 創建JwtTokenServiceImpl作為JWT處理的業務類,添加根據HMAC算法生成和解析JWT令牌的方法,可以發現nimbus-jose-jwt庫操作JWT的API非常易于理解;
/**
?*?Created?by?macro?on?2020/6/22.
?*/
@Service
public?class?JwtTokenServiceImpl?implements?JwtTokenService?{
????@Override
????public?String?generateTokenByHMAC(String?payloadStr,?String?secret)?throws?JOSEException?{
????????//創建JWS頭,設置簽名算法和類型
????????JWSHeader?jwsHeader?=?new?JWSHeader.Builder(JWSAlgorithm.HS256).
????????????????type(JOSEObjectType.JWT)
????????????????.build();
????????//將負載信息封裝到Payload中
????????Payload?payload?=?new?Payload(payloadStr);
????????//創建JWS對象
????????JWSObject?jwsObject?=?new?JWSObject(jwsHeader,?payload);
????????//創建HMAC簽名器
????????JWSSigner?jwsSigner?=?new?MACSigner(secret);
????????//簽名
????????jwsObject.sign(jwsSigner);
????????return?jwsObject.serialize();
????}

????@Override
????public?PayloadDto?verifyTokenByHMAC(String?token,?String?secret)?throws?ParseException,?JOSEException?{
????????//從token中解析JWS對象
????????JWSObject?jwsObject?=?JWSObject.parse(token);
????????//創建HMAC驗證器
????????JWSVerifier?jwsVerifier?=?new?MACVerifier(secret);
????????if?(!jwsObject.verify(jwsVerifier))?{
????????????throw?new?JwtInvalidException("token簽名不合法!");
????????}
????????String?payload?=?jwsObject.getPayload().toString();
????????PayloadDto?payloadDto?=?JSONUtil.toBean(payload,?PayloadDto.class);
????????if?(payloadDto.getExp()?new?Date().getTime())?{
????????????throw?new?JwtExpiredException("token已過期!");
????????}
????????return?payloadDto;
????}
}
  • 創建PayloadDto實體類,用于封裝JWT中存儲的信息;
/**
?*?Created?by?macro?on?2020/6/22.
?*/
@Data
@EqualsAndHashCode(callSuper?=?false)
@Builder
public?class?PayloadDto?{
????@ApiModelProperty("主題")
????private?String?sub;
????@ApiModelProperty("簽發時間")
????private?Long?iat;
????@ApiModelProperty("過期時間")
????private?Long?exp;
????@ApiModelProperty("JWT的ID")
????private?String?jti;
????@ApiModelProperty("用戶名稱")
????private?String?username;
????@ApiModelProperty("用戶擁有的權限")
????private?List?authorities;
}
  • 在JwtTokenServiceImpl類中添加獲取默認的PayloadDto的方法,JWT過期時間設置為60min;
/**
?*?Created?by?macro?on?2020/6/22.
?*/
@Service
public?class?JwtTokenServiceImpl?implements?JwtTokenService?{
????@Override
????public?PayloadDto?getDefaultPayloadDto()?{
????????Date?now?=?new?Date();
????????Date?exp?=?DateUtil.offsetSecond(now,?60*60);
????????return?PayloadDto.builder()
????????????????.sub("macro")
????????????????.iat(now.getTime())
????????????????.exp(exp.getTime())
????????????????.jti(UUID.randomUUID().toString())
????????????????.username("macro")
????????????????.authorities(CollUtil.toList("ADMIN"))
????????????????.build();
????}
}
  • 創建JwtTokenController類,添加根據HMAC算法生成和解析JWT令牌的接口,由于HMAC算法需要長度至少為32個字節的秘鑰,所以我們使用MD5加密下;
/**
?*?JWT令牌管理Controller
?*?Created?by?macro?on?2020/6/22.
?*/
@Api(tags?=?"JwtTokenController",?description?=?"JWT令牌管理")
@Controller
@RequestMapping("/token")
public?class?JwtTokenController?{

????@Autowired
????private?JwtTokenService?jwtTokenService;

????@ApiOperation("使用對稱加密(HMAC)算法生成token")
????@RequestMapping(value?=?"/hmac/generate",?method?=?RequestMethod.GET)
????@ResponseBody
????public?CommonResult?generateTokenByHMAC()?{
????????try?{
????????????PayloadDto?payloadDto?=?jwtTokenService.getDefaultPayloadDto();
????????????String?token?=?jwtTokenService.generateTokenByHMAC(JSONUtil.toJsonStr(payloadDto),?SecureUtil.md5("test"));
????????????return?CommonResult.success(token);
????????}?catch?(JOSEException?e)?{
????????????e.printStackTrace();
????????}
????????return?CommonResult.failed();
????}

????@ApiOperation("使用對稱加密(HMAC)算法驗證token")
????@RequestMapping(value?=?"/hmac/verify",?method?=?RequestMethod.GET)
????@ResponseBody
????public?CommonResult?verifyTokenByHMAC(String?token)?{
????????try?{
????????????PayloadDto?payloadDto??=?jwtTokenService.verifyTokenByHMAC(token,?SecureUtil.md5("test"));
????????????return?CommonResult.success(payloadDto);
????????}?catch?(ParseException?|?JOSEException?e)?{
????????????e.printStackTrace();
????????}
????????return?CommonResult.failed();

????}
}
  • 調用使用HMAC算法生成JWT令牌的接口進行測試;
  • 調用使用HMAC算法解析JWT令牌的接口進行測試。

非對稱加密(RSA)

非對稱加密指的是使用公鑰和私鑰來進行加密解密操作。對于加密操作,公鑰負責加密,私鑰負責解密,對于簽名操作,私鑰負責簽名,公鑰負責驗證。非對稱加密在JWT中的使用顯然屬于簽名操作。

  • 如果我們需要使用固定的公鑰和私鑰來進行簽名和驗證的話,我們需要生成一個證書文件,這里將使用Java自帶的keytool工具來生成jks證書文件,該工具在JDK的bin目錄下;
  • 打開CMD命令界面,使用如下命令生成證書文件,設置別名為jwt,文件名為jwt.jks;
keytool?-genkey?-alias?jwt?-keyalg?RSA?-keystore?jwt.jks
  • 輸入密碼為123456,然后輸入各種信息之后就可以生成證書jwt.jks文件了;
  • 將證書文件jwt.jks復制到項目的resource目錄下,然后需要從證書文件中讀取RSAKey,這里我們需要在pom.xml中添加一個Spring Security的RSA依賴;

<dependency>
????<groupId>org.springframework.securitygroupId>
????<artifactId>spring-security-rsaartifactId>
????<version>1.0.7.RELEASEversion>
dependency>
  • 然后在JwtTokenServiceImpl類中添加方法,從類路徑下讀取證書文件并轉換為RSAKey對象;
/**
?*?Created?by?macro?on?2020/6/22.
?*/
@Service
public?class?JwtTokenServiceImpl?implements?JwtTokenService?{
????@Override
????public?RSAKey?getDefaultRSAKey()?{
????????//從classpath下獲取RSA秘鑰對
????????KeyStoreKeyFactory?keyStoreKeyFactory?=?new?KeyStoreKeyFactory(new?ClassPathResource("jwt.jks"),?"123456".toCharArray());
????????KeyPair?keyPair?=?keyStoreKeyFactory.getKeyPair("jwt",?"123456".toCharArray());
????????//獲取RSA公鑰
????????RSAPublicKey?publicKey?=?(RSAPublicKey)?keyPair.getPublic();
????????//獲取RSA私鑰
????????RSAPrivateKey?privateKey?=?(RSAPrivateKey)?keyPair.getPrivate();
????????return?new?RSAKey.Builder(publicKey).privateKey(privateKey).build();
????}
}
  • 我們可以在JwtTokenController中添加一個接口,用于獲取證書中的公鑰;
/**
?*?JWT令牌管理Controller
?*?Created?by?macro?on?2020/6/22.
?*/
@Api(tags?=?"JwtTokenController",?description?=?"JWT令牌管理")
@Controller
@RequestMapping("/token")
public?class?JwtTokenController?{

????@Autowired
????private?JwtTokenService?jwtTokenService;
????
????@ApiOperation("獲取非對稱加密(RSA)算法公鑰")
????@RequestMapping(value?=?"/rsa/publicKey",?method?=?RequestMethod.GET)
????@ResponseBody
????public?Object?getRSAPublicKey()?{
????????RSAKey?key?=?jwtTokenService.getDefaultRSAKey();
????????return?new?JWKSet(key).toJSONObject();
????}
}
  • 調用該接口,查看公鑰信息,公鑰是可以公開訪問的;
  • 在JwtTokenServiceImpl中添加根據RSA算法生成和解析JWT令牌的方法,可以發現和上面的HMAC算法操作基本一致;
/**
?*?Created?by?macro?on?2020/6/22.
?*/
@Service
public?class?JwtTokenServiceImpl?implements?JwtTokenService?{
????@Override
????public?String?generateTokenByRSA(String?payloadStr,?RSAKey?rsaKey)?throws?JOSEException?{
????????//創建JWS頭,設置簽名算法和類型
????????JWSHeader?jwsHeader?=?new?JWSHeader.Builder(JWSAlgorithm.RS256)
????????????????.type(JOSEObjectType.JWT)
????????????????.build();
????????//將負載信息封裝到Payload中
????????Payload?payload?=?new?Payload(payloadStr);
????????//創建JWS對象
????????JWSObject?jwsObject?=?new?JWSObject(jwsHeader,?payload);
????????//創建RSA簽名器
????????JWSSigner?jwsSigner?=?new?RSASSASigner(rsaKey,?true);
????????//簽名
????????jwsObject.sign(jwsSigner);
????????return?jwsObject.serialize();
????}

????@Override
????public?PayloadDto?verifyTokenByRSA(String?token,?RSAKey?rsaKey)?throws?ParseException,?JOSEException?{
????????//從token中解析JWS對象
????????JWSObject?jwsObject?=?JWSObject.parse(token);
????????RSAKey?publicRsaKey?=?rsaKey.toPublicJWK();
????????//使用RSA公鑰創建RSA驗證器
????????JWSVerifier?jwsVerifier?=?new?RSASSAVerifier(publicRsaKey);
????????if?(!jwsObject.verify(jwsVerifier))?{
????????????throw?new?JwtInvalidException("token簽名不合法!");
????????}
????????String?payload?=?jwsObject.getPayload().toString();
????????PayloadDto?payloadDto?=?JSONUtil.toBean(payload,?PayloadDto.class);
????????if?(payloadDto.getExp()?new?Date().getTime())?{
????????????throw?new?JwtExpiredException("token已過期!");
????????}
????????return?payloadDto;
????}
}
  • 在JwtTokenController類,添加根據RSA算法生成和解析JWT令牌的接口,使用默認的RSA鑰匙對;
/**
?*?JWT令牌管理Controller
?*?Created?by?macro?on?2020/6/22.
?*/
@Api(tags?=?"JwtTokenController",?description?=?"JWT令牌管理")
@Controller
@RequestMapping("/token")
public?class?JwtTokenController?{

????@Autowired
????private?JwtTokenService?jwtTokenService;

????@ApiOperation("使用非對稱加密(RSA)算法生成token")
????@RequestMapping(value?=?"/rsa/generate",?method?=?RequestMethod.GET)
????@ResponseBody
????public?CommonResult?generateTokenByRSA()?{
????????try?{
????????????PayloadDto?payloadDto?=?jwtTokenService.getDefaultPayloadDto();
????????????String?token?=?jwtTokenService.generateTokenByRSA(JSONUtil.toJsonStr(payloadDto),jwtTokenService.getDefaultRSAKey());
????????????return?CommonResult.success(token);
????????}?catch?(JOSEException?e)?{
????????????e.printStackTrace();
????????}
????????return?CommonResult.failed();
????}

????@ApiOperation("使用非對稱加密(RSA)算法驗證token")
????@RequestMapping(value?=?"/rsa/verify",?method?=?RequestMethod.GET)
????@ResponseBody
????public?CommonResult?verifyTokenByRSA(String?token)?{
????????try?{
????????????PayloadDto?payloadDto??=?jwtTokenService.verifyTokenByRSA(token,?jwtTokenService.getDefaultRSAKey());
????????????return?CommonResult.success(payloadDto);
????????}?catch?(ParseException?|?JOSEException?e)?{
????????????e.printStackTrace();
????????}
????????return?CommonResult.failed();
????}
}
  • 調用使用RSA算法生成JWT令牌的接口進行測試;
  • 調用使用RSA算法解析JWT令牌的接口進行測試。

參考資料

官方文檔:https://connect2id.com/products/nimbus-jose-jwt

項目源碼地址

https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-jwt

推薦閱讀

  • 線上項目出BUG沒法調試?推薦這款阿里開源的診斷神器!
  • Spring Boot 把 Maven 干掉了,正式擁抱 Gradle!
  • 性能優越的輕量級日志收集工具,微軟、亞馬遜都在用!
  • 15個Github使用技巧,你肯定有不知道的!
  • 寫了100多篇原創文章,我常用的在線工具網站推薦給大家!
  • 還在用Swagger生成接口文檔?我推薦你試試它.....
  • 你居然還去服務器上撈日志,搭個日志收集系統難道不香么!
  • 真慘!連各大編程語言都擺起地攤了,Java攤位真大!
  • 一個不容錯過的Spring Cloud實戰項目!
  • 我的Github開源項目,從0到20000 Star!

歡迎關注,點個在看

總結

以上是生活随笔為你收集整理的golang jwt设置过期_听说你的JWT库用起来特别扭,推荐这款贼好用的!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。