Java 有许多比较知名的生成 JWT(JSON WEB TOKEN)的开源工具库。例如

选择性比较多,本文以常用的 auth0 组织下的 java-jwt 为例。

引入java-jwt

pom.xml 文件中引入 java-jwt

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.19.1</version>
</dependency>

JwtUtil

编写一个 JwtUtil 工具类,用以生成 Token 令牌以及校验 Token 令牌。该工具类还需要依赖一个配置类来实现。

@Component
public class JwtUtil {
	private static String tokenSecret;
	private static Long tokenExpire;
	private static Algorithm algorithm;

	@Autowired
	public JwtUtil(JwtConfig jwtConfig, UserService userService) {
		JwtUtil.tokenSecret = jwtConfig.getTokenSecret();
		JwtUtil.tokenExpire = jwtConfig.getTokenExpire();
		JwtUtil.algorithm = Algorithm.HMAC512(JwtUtil.tokenSecret);
		JwtUtil.userService = userService;
	}

	/**
	 * 生成Token
	 */
	public static String generateToken(String userId) {
		long now = new Date().getTime();
		Date expireDate = new Date(now + (JwtUtil.tokenExpire));

		return JWT.create()
				.withClaim("userId", userId)
				.withExpiresAt(expireDate)
				.sign(JwtUtil.algorithm);
	}

	/**
	 * 验证Token
	 */
	public static boolean verifyToken(String token) {
		try {
			JWTVerifier verifier = JWT.require(JwtUtil.algorithm)
					.acceptExpiresAt(JwtUtil.tokenExpire)
					.build();
			verifier.verify(token);
			return true;
		} catch (TokenExpiredException e) {
			throw new TokenExpired();
		} catch (JWTVerificationException e) {
			throw new TokenInvalid();
		}
	}

	/**
	 * 获取Claim
	 */
	public static String getClaim(String token, String claimKey) {
		DecodedJWT jwt = JWT.decode(token);
		return jwt.getClaims().get(claimKey).asString();
	}
}
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "jwt")
public class JwtConfig {
	private String tokenSecret;
	private Long tokenExpire;
}

使用

JwtUtil 可以在授权登录成功后生成令牌,并下发至客户端。

String token = JwtUtil.generateToken(user.getId());

使用拦截器,拦截校验 JWT 令牌是否合法。

@Component
public class JwtInterceptor implements HandlerInterceptor {
	public final static String AUTHORIZATION_HEADER = "Authorization";
	public final static String BEARER_PATTERN = "^Token$";

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		String token = verifyAuthorizationHeader(request);
		return JwtUtil.verifyToken(token);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		LocalUser.clearLocalUser();
	}

	/**
	 * 验证请求头是否携带Token
	 */
	private String verifyAuthorizationHeader(HttpServletRequest request) {
		String authorization = request.getHeader(AUTHORIZATION_HEADER);
		if (authorization == null) {
			throw new AuthorizationException();
		}
		String[] splits = authorization.split(" ");
		if (splits.length != 2) {
			throw new AuthorizationException();
		}
		String scheme = splits[0];
		String token = splits[1];
		if (!Pattern.matches(BEARER_PATTERN, scheme)) {
			throw new AuthorizationException();
		}
		return token;
	}
}

标题:Spring Boot构建Web API Wheel(五)—— JWT令牌
作者:Jeffrey