seo优化多少钱,电商类网站怎么做 seo,国外网站有备案吗,wordpress全站备份以前一直使用的是jjwt这个JWT库#xff0c;虽然小巧够用, 但对JWT的一些细节封装的不是很好。最近发现了一个更好用的JWT库nimbus-jose-jwt#xff0c;简单易用#xff0c;API非常易于理解#xff0c;对称加密和非对称加密算法都支持#xff0c;推荐给大家#xff01;简介… 以前一直使用的是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 groupIdcom.nimbusdsgroupId artifactIdnimbus-jose-jwtartifactId version8.16versiondependency创建JwtTokenServiceImpl作为JWT处理的业务类添加根据HMAC算法生成和解析JWT令牌的方法可以发现nimbus-jose-jwt库操作JWT的API非常易于理解/** * Created by macro on 2020/6/22. */Servicepublic 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. */DataEqualsAndHashCode(callSuper false)Builderpublic 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. */Servicepublic 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令牌管理)ControllerRequestMapping(/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.jkskeytool -genkey -alias jwt -keyalg RSA -keystore jwt.jks输入密码为123456然后输入各种信息之后就可以生成证书jwt.jks文件了将证书文件jwt.jks复制到项目的resource目录下然后需要从证书文件中读取RSAKey这里我们需要在pom.xml中添加一个Spring Security的RSA依赖dependency groupIdorg.springframework.securitygroupId artifactIdspring-security-rsaartifactId version1.0.7.RELEASEversiondependency然后在JwtTokenServiceImpl类中添加方法从类路径下读取证书文件并转换为RSAKey对象/** * Created by macro on 2020/6/22. */Servicepublic 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令牌管理)ControllerRequestMapping(/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. */Servicepublic 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令牌管理)ControllerRequestMapping(/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欢迎关注点个在看