3.服务器接收到用户的token后,进行验证用户的身份、权限、有效期等信息,验证通过即放行,验证不通过就拒绝服务;
3.签名signature,使用指定的算法以及密钥,对前两部分进行签名得到的字符串,主要目的是为了防篡改;
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJaSEFOR1hVTiIsImJvZHkiOnsidXNlclJvbGUiOiJhZG1pbiIsInVzZXJpZCI6IjAwMSJ9LCJleHAiOjE2NjI5NTIxNjIsImlhdCI6MTY2Mjk1MTU1NywianRpIjoiZGZhN2MyZjUtNGNjMC00OWFhLWFiMDUtYzZhY2M4M2YxMDViIn0.xOleM21i7-EI0oOq83Xm-nQVOufajHCupY2QjkpwreQ
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>4.0.0</version> </dependency> @Slf4j @RestController public class TokenController { @Autowired private TokenUtil tokenUtil; @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password){ if(!"admin".equals(username) || !"123".equals(password)){ log.info("账号或者密码错误!"); } // 堆代码 duidaima.com // 模拟从数据库中获取的用户识别信息 String userId = "001"; String userRole = "admin"; Map<String,Object> dataMap = new HashMap<>(); dataMap.put("userId", userId); dataMap.put("userRole", userRole); // 将用户识别信息存储到token中 String token = tokenUtil.createToken(dataMap); log.info("生成的token为:{}", token); return token; } @PostMapping("/getUserInfo") public String getUserInfo(@RequestParam String token){ if(ObjectUtils.isEmpty(token)){ log.info("token不能为空!"); return "token不能为空!"; } log.info("收到的token为:{}", token); Map<String, Object> dataMap = tokenUtil.parseToken(token); String userRole = dataMap.get("userRole").toString(); if(!"admin".equals(userRole)){ log.info("非管理员角色,不允许访问!"); return "非管理员角色,不允许访问!"; } String userId = dataMap.get("userId").toString(); return "允许登录,用户为:" + userId; } } @Component public class TokenUtil { /** * 默认密钥 */ private static final String DEFAULT_SECRET = "999"; private static final String DEFAULT_DATA_KEY = "body"; private static final String DEFAULT_ISSUER = "ZHANGXUN"; private static final Long DEFAULT_EXPIRE_TIME = 7*24*60*60L; public String createToken(Map<String, Object> dataMap){ return createToken(dataMap, DEFAULT_SECRET); } public String createToken(Map<String, Object> dataMap, String secret){ // 指定使用的加密算法 Algorithm algorithm = Algorithm.HMAC256(secret); return JWT.create() .withClaim(DEFAULT_DATA_KEY, dataMap) .withIssuer(DEFAULT_ISSUER) .withIssuedAt(new Date()) .withExpiresAt(new Date(System.currentTimeMillis() + DEFAULT_EXPIRE_TIME * 1000)) .withJWTId(UUID.randomUUID().toString()) .sign(algorithm); } public Map<String, Object> parseToken(String token){ return parseToken(token, DEFAULT_SECRET); } public Map<String, Object> parseToken(String token, String secret){ // 指定使用的加密算法 Algorithm algorithm = Algorithm.HMAC256(secret); JWTVerifier jwtVerifier = JWT.require(algorithm).build(); DecodedJWT decodedJWT = jwtVerifier.verify(token); return decodedJWT.getClaim(DEFAULT_DATA_KEY).asMap(); } }
扩展性强,对于分布式系统,JWT天然支持应用水平扩展,无需修改任何代码;