JWT 和 JJWT 的区别(别再傻傻分不清了。。)

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

  • Header: 标题包含了令牌的元数据,并且在最小包含签名和/或加密算法的类型
  • Claims: Claims包含您想要签署的任何信息
  • JSON Web Signature (JWS): 在header中指定的使用该算法的数字签名和声明
例如:
Header:{ "alg": "HS256", "typ": "JWT" }Claims:{ "sub": "1234567890", "name": "John Doe", "admin": true }Signature:base64UrlEncode(Header) + "." + base64UrlEncode(Claims),

加密生成的token:
JWT 和 JJWT 的区别(别再傻傻分不清了。。)
文章图片

如何保证 JWT 安全 有很多库可以帮助您创建和验证JWT,但是当使用JWT时,仍然可以做一些事情来限制您的安全风险。在您信任JWT中的任何信息之前,请始终验证签名。这应该是给定的。
换句话说,如果您正在传递一个秘密签名密钥到验证签名的方法,并且签名算法被设置为“none”,那么它应该失败验证。
确保签名的秘密签名,用于计算和验证签名。秘密签名密钥只能由发行者和消费者访问,不能在这两方之外访问。
不要在JWT中包含任何敏感数据。这些令牌通常是用来防止操作(未加密)的,因此索赔中的数据可以很容易地解码和读取。
如果您担心重播攻击,包括一个nonce(jti索赔)、过期时间(exp索赔)和创建时间(iat索赔)。这些在JWT规范中定义得很好。
JWT 和 JJWT 的区别(别再傻傻分不清了。。)
文章图片

jwt的框架:JJWT JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。
  • JJWT的目标是最容易使用和理解用于在JVM上创建和验证JSON Web令牌(JWTs)的库。
  • JJWT是基于JWT、JWS、JWE、JWK和JWA RFC规范的Java实现。
  • JJWT还添加了一些不属于规范的便利扩展,比如JWT压缩和索赔强制。
规范兼容:
  • 创建和解析明文压缩JWTs
  • 创建、解析和验证所有标准JWS算法的数字签名紧凑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演示,理解原理,集成到自己项目中即可。
应用采用 spring boot + angular + jwt 结构图
JWT 和 JJWT 的区别(别再傻傻分不清了。。)
文章图片

Maven 引进 : pom.xml
4.0.0 com.nibado.example jwt-angular-spring 0.0.2-SNAPSHOT1.8 1.82.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}

WebApplication.java
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); }}

JwtFilter.java
package com.nibado.example.jwtangspr; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.springframework.web.filter.GenericFilterBean; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureException; public class JwtFilter extends GenericFilterBean {@Override public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) req; //客户端将token封装在请求头中,格式为(Bearer后加空格):Authorization:Bearer +token final String authHeader = request.getHeader("Authorization"); if (authHeader == null || !authHeader.startsWith("Bearer ")) { throw new ServletException("Missing or invalid Authorization header."); }//去除Bearer 后部分 final String token = authHeader.substring(7); try { //解密token,拿到里面的对象claims final Claims claims = Jwts.parser().setSigningKey("secretkey") .parseClaimsJws(token).getBody(); //将对象传递给下一个请求 request.setAttribute("claims", claims); } catch (final SignatureException e) { throw new ServletException("Invalid token."); }chain.doFilter(req, res); }}

UserController.java
package com.nibado.example.jwtangspr; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @RestController @RequestMapping("/user") public class UserController { //这里模拟数据库 private final Map> userDb = new HashMap<>(); @SuppressWarnings("unused") private static class UserLogin { public String name; public String password; }public UserController() { userDb.put("tom", Arrays.asList("user")); userDb.put("wen", Arrays.asList("user", "admin")); } /*以上是模拟数据库,并往数据库插入tom和sally两条记录*/@RequestMapping(value = "https://www.it610.com/article/login", method = RequestMethod.POST) public LoginResponse login(@RequestBody final UserLogin login) throws ServletException { if (login.name == null || !userDb.containsKey(login.name)) { throw new ServletException("Invalid login"); }//加密生成token return new LoginResponse(Jwts.builder().setSubject(login.name) .claim("roles", userDb.get(login.name)).setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256, "secretkey").compact()); }@SuppressWarnings("unused") private static class LoginResponse { public String token; public LoginResponse(final String token) { this.token = token; } } }

ApiController.java
package com.nibado.example.jwtangspr; import io.jsonwebtoken.Claims; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class ApiController { @SuppressWarnings("unchecked") @RequestMapping(value = "https://www.it610.com/article/role/{role}", method = RequestMethod.GET) public Boolean login(@PathVariable final String role, final HttpServletRequest request) throws ServletException { final Claims claims = (Claims) request.getAttribute("claims"); return ((List) claims.get("roles")).contains(role); } }

index.html
JSON Web Token / AngularJS / Spring Boot example {{greeting}} Please log in (tom and sally are valid names)
Username:
Error: {{error.data.message}} Success! Welcome {{userName}}
(logout){{userName}} is aUserAdminFoo

app.js
var appModule = angular.module('myApp', []); appModule.controller('MainCtrl', ['mainService','$scope','$http', function(mainService, $scope, $http) { $scope.greeting = 'Welcome to the JSON Web Token / AngularJR / Spring example!'; $scope.token = null; $scope.error = null; $scope.roleUser = false; $scope.roleAdmin = false; $scope.roleFoo = false; $scope.login = function() { $scope.error = null; mainService.login($scope.userName).then(function(token) { $scope.token = token; $http.defaults.headers.common.Authorization = 'Bearer ' + token; $scope.checkRoles(); }, function(error){ $scope.error = error $scope.userName = ''; }); }$scope.checkRoles = function() { mainService.hasRole('user').then(function(user) {$scope.roleUser = user}); mainService.hasRole('admin').then(function(admin) {$scope.roleAdmin = admin}); mainService.hasRole('foo').then(function(foo) {$scope.roleFoo = foo}); }$scope.logout = function() { $scope.userName = ''; $scope.token = null; $http.defaults.headers.common.Authorization = ''; }$scope.loggedIn = function() { return $scope.token !== null; } } ]); appModule.service('mainService', function($http) { return { login : function(username) { return $http.post('/user/login', {name: username}).then(function(response) { return response.data.token; }); },hasRole : function(role) { return $http.get('/api/role/' + role).then(function(response){ console.log(response); return response.data; }); } }; });

运行应用
JWT 和 JJWT 的区别(别再傻傻分不清了。。)
文章图片

效果
JWT 和 JJWT 的区别(别再傻傻分不清了。。)
文章图片

JWT 和 JJWT 的区别(别再傻傻分不清了。。)
文章图片

原文链接:https://blog.csdn.net/change_...
版权声明:本文为CSDN博主「J_小浩子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2021最新版)
2.别在再满屏的 if/ else 了,试试策略模式,真香!!
3.卧槽!Java 中的 xx ≠ null 是什么新语法?
4.Spring Boot 2.5 重磅发布,黑暗模式太炸了!
5.《Java开发手册(嵩山版)》最新发布,速速下载!
【JWT 和 JJWT 的区别(别再傻傻分不清了。。)】觉得不错,别忘了随手点赞+转发哦!

    推荐阅读