1. pom.xml
4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.rib-pet SwaggerConfig 0.0.1-SNAPSHOT demo Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.projectlombok lombok 1.18.16 org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 runtime io.springfox springfox-swagger2 2.8.0 compile io.springfox springfox-swagger-ui 2.8.0 compile org.apache.commons commons-lang3 io.jsonwebtoken jjwt 0.9.1 org.springframework.boot spring-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;
}