Spring boot + JWT 實現安全驗證 ---auth0.jwt


參考 http://auth0 / java-jwt

auth0的jwt 實現安全驗證: 使用自定義參數 和時間戳生成token。驗證token時驗證自定義參數。auth0.jwt 驗證token時會自動驗證時間戳是否過期,如果過期,會拋出異常TokenExpiredException

1.引入依賴

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
	<groupId>com.auth0</groupId>
	<artifactId>java-jwt</artifactId>
	<version>3.10.3</version>
</dependency>

2.生成token和驗證token的工具類

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;

@Component
public class TokenUtil {

	@Value("${jwt.issuer}")
	private String ISSUER;//project-name

	@Value("${jwt.audience}")
	private String AUDIENCE;//web

	@Value("${jwt.expires_in}")
	private int EXPIRES_IN;//30

	private String encryKey = "project-name";

	private Algorithm ALGORITHM = Algorithm.HMAC256(encryKey);

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	public static Boolean result = false;
	public static String message = "";

	public String generateToken(String username) {

		
		long currentTime = System.currentTimeMillis();
		logger.info("=====generateToken===now    is " + new Date(currentTime));
		logger.info("=====generateToken===expire is " + new Date(currentTime + EXPIRES_IN * 1000 * 60));

		String token = JWT.create()

				.withIssuer(ISSUER)

				.withIssuedAt(new Date(currentTime))// 簽發時間

				.withExpiresAt(new Date(currentTime + EXPIRES_IN * 1000 * 60))// 過期時間戳

				.withClaim("username", username)//自定義參數

				.sign(ALGORITHM);

		return token;
	}

	public void verifyToken(String token) {

		try {

			if (null == token) {
				result = false;
				message = "token is null";
				return;
			}
			// Reusable verifier instance
			JWTVerifier verifier = JWT.require(ALGORITHM)

					.withIssuer(ISSUER)

					.build();
			DecodedJWT decodedJWT = verifier.verify(token);

			// verify issuer
			String issuer = decodedJWT.getIssuer();

			// verity 自定義參數
			String username = decodedJWT.getClaim("username").asString();
			if (("").equals(username)) {
				result = false;
				message = "user is error";
				return;
			}

		} catch (TokenExpiredException e) {
			result = false;
			message = "token is expired";
			return;
		}
		result = true;
		message = "token is verified";

	}

}

3. 把token的生成和驗證工具 添加到spring 攔截器中

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class TokenInterceptor extends HandlerInterceptorAdapter {

	private TokenHelper tokenHelper;

	public TokenInterceptor(TokenHelper tokenHelper) {
		this.tokenHelper = tokenHelper;
	}

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		// verify token
		tokenHelper.verifyToken(request.getHeader("token"));

		// result
		if (TokenHelper.result) {
			return true;
		} else {
			response.setStatus(403);
			logger.error(TokenHelper.message);
			return false;
		}

	}

}

4.注冊攔截器

import java.util.ArrayList;
import java.util.List;

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 WebConfig implements WebMvcConfigurer {

	@Autowired
	private TokenHelper tokenHelper;

	@Override
	public void addInterceptors(InterceptorRegistry registry) {

		List<String> excludePath = new ArrayList<>();
		// 獲取token 不要驗證
		excludePath.add("/api/generateToken");

		registry.addInterceptor(new TokenInterceptor(tokenHelper))

				.addPathPatterns("/**")

				.excludePathPatterns(excludePath);
	}

}

5.生成token測試

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class TokenController {

	@Autowired
	private TokenHelper tokenHelper;

	@PostMapping(value = "/generateToken")
	public String generateToken(@RequestParam("username") String username) {
		return tokenHelper.generateToken(username);

	}

}

6.其它url訪問項目 都需要在請求頭部帶着token否則會失敗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM