Java JTW implementation

1. pom.xml  4.0.0org.springframework.bootspring-boot-starter-parent2.4.1 com.rib

1. pom.xml 


4.0.0org.springframework.bootspring-boot-starter-parent2.4.1 com.rib-petSwaggerConfig0.0.1-SNAPSHOTdemoDemo project for Spring Boot1.8org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testtestorg.projectlomboklombok1.18.16org.springframework.bootspring-boot-starter-data-jpacom.h2databaseh2runtimeio.springfoxspringfox-swagger22.8.0compileio.springfoxspringfox-swagger-ui2.8.0compileorg.apache.commonscommons-lang3io.jsonwebtokenjjwt0.9.1org.springframework.bootspring-boot-maven-plugin

applicaiton.yml as below:

# token配置
token:# 令牌自定义标识header: Authorization# 令牌密钥(自定义)secret: 6F3931D35F0395DF82B032B8019AC57D# 令牌有效期(默认30分钟)expireTime: 30

2. TokenService.java

package com.ribpet.component;import org.springframework.stereotype.Component;import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;import org.springframework.beans.factory.annotation.Value;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;@Component
public class TokenService {/*** 生成Token** @param sub* @return*/public String createToken(String sub) {Calendar calendar = GregorianCalendar.getInstance();Date iat = calendar.getTime();calendar.add(GregorianCalendar.MINUTE, amount);Date exp = calendar.getTime();return Jwts.builder()//.setHeaderParam("typ", "JWT")// 令牌类型.setSubject(sub)// 主题.setIssuedAt(iat) // 签发时间.setExpiration(exp)// 过期时间.signWith(SignatureAlgorithm.HS512, secretKey)// 签名算法、秘钥.compact();}/*** 获取Token中注册信息** @param token* @return*/public Claims getBody(String token) {return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();}/*** 获取签发日期** @param token* @return*/public Date getIssuedAt(String token) {return getBody(token).getIssuedAt();}/*** 获取过期时间** @param token* @return*/public Date getExpiration(String token) {return getBody(token).getExpiration();}/*** 获取主题信息** @param token* @return*/public String getSubject(String token) {return getBody(token).getSubject();}// 令牌秘钥@Value("${token.secret}")private String secretKey;// 令牌有效期(默认30分钟)@Value("${token.expireTime}")private int    amount;
}

token interceptor implement

package com.ribpet.component;import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.SignatureException;@Component
public class TokenHandlerInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {String uri = request.getRequestURI();if (uri.contains("/login")) {return true;}String token = request.getHeader(header);if (StringUtils.isBlank(token)) {throw new SignatureException(StringUtils.EMPTY);}tokenService.getBody(token);return true;}@Autowiredprivate TokenService tokenService;// 令牌自定义标识@Value("${token.header}")private String       header;
}

ResouceConfig.java

package com.ribpet.config;import com.ribpet.component.TokenHandlerInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class ResourceConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(tokenHandlerInterceptor).addPathPatterns("/**");}@Autowiredprivate TokenHandlerInterceptor tokenHandlerInterceptor;
}

HttpStatus

package com.ribpet.constants;public final class HttpStatus {public static final int OK                    = 200;public static final int INTERNAL_SERVER_ERROR = 500;private HttpStatus() {// DO NOTHING}}

AjaxResult

package com.ribpet.dto;import com.ribpet.constants.HttpStatus;import java.util.HashMap;
import java.util.Objects;public class AjaxResult extends HashMap {private static final long   serialVersionUID = 242180064461040653L;// 状态码private static final String CODE_TAG         = "code";// 返回内容private static final String MSG_TAG          = "msg";// 数据对象private static final String DATA_TAG         = "data";public AjaxResult() {// DO NOTHING}public AjaxResult(int code, String msg) {super.put(CODE_TAG, code);super.put(MSG_TAG, msg);}public AjaxResult(int code, String msg, Object data) {this(code, msg);if (Objects.nonNull(data)) {super.put(DATA_TAG, data);}}public static AjaxResult success() {return AjaxResult.success("操作成功");}public static AjaxResult success(Object object) {return AjaxResult.success("操作成功", object);}public static AjaxResult success(String msg) {return AjaxResult.success(msg, null);}public static AjaxResult success(String msg, Object data) {return new AjaxResult(HttpStatus.OK, msg, data);}public static AjaxResult error() {return AjaxResult.success("操作失败");}public static AjaxResult error(Object object) {return AjaxResult.error("操作失败", object);}public static AjaxResult error(String msg) {return AjaxResult.error(msg, null);}public static AjaxResult error(String msg, Object data) {return new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR, msg, data);}
}

Exception

package com.ribpet.exceptions;import com.ribpet.dto.AjaxResult;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(SignatureException.class)@ResponseBodypublic AjaxResult signatureException() {return AjaxResult.error("Token为空");}@ResponseBody@ExceptionHandler(ExpiredJwtException.class)public AjaxResult expiredJwtException() {return AjaxResult.error("Token过期");}@ResponseBody@ExceptionHandler(MalformedJwtException.class)public AjaxResult malformedJwtException() {return AjaxResult.error("Token数据错误");}
}

controller

package com.ribpet.controller;import com.ribpet.component.TokenService;
import com.ribpet.dto.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;@RestController
public class IndexController {@PostMapping(path = "/login", produces = APPLICATION_JSON_VALUE)public AjaxResult login(String username, String password) {// 模拟数据库操作if ("admin".equals(username) && "admin123".equals(password)) {return AjaxResult.success("操作成功", tokenService.createToken(username));}return AjaxResult.error("账号或密码错误");}@GetMapping(path = "/index", produces = APPLICATION_JSON_VALUE)public AjaxResult execute(@RequestHeader("Authorization") String token) {return AjaxResult.success(tokenService.getSubject(token));}@Autowiredprivate TokenService tokenService;
}

github link https://github.com/rib-pet/SwaggerConfig