crm-rest-api/src/main/java/com/goi/erp/token/JwtService.java

150 lines
4.6 KiB
Java

package com.goi.erp.token;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.goi.erp.common.permission.PermissionParser;
import com.goi.erp.common.permission.PermissionSet;
import java.security.Key;
import java.util.List;
import java.util.function.Function;
/**
* - DB 접근 없음
* - JWT에 포함된 empUuid, 이름, roles, permissions 추출
* - 토큰 유효기간 체크 가능
*/
@Service
public class JwtService {
@Value("${application.security.jwt.secret-key}")
private String secretKey;
@Value("${application.security.jwt.expiration}")
private long jwtExpiration;
/**
* empUuid(sub) 추출
*/
public String extractEmpUuid(String token) {
return extractClaim(token, Claims::getSubject);
}
/**
* loginId 추출
*/
public String extractLoginId(String token) {
return extractClaim(token, claims -> claims.get("loginId", String.class));
}
/**
* firstName 추출
*/
public String extractFirstName(String token) {
return extractClaim(token, claims -> claims.get("firstName", String.class));
}
/**
* lastName 추출
*/
public String extractLastName(String token) {
return extractClaim(token, claims -> claims.get("lastName", String.class));
}
/**
* roles 리스트 추출
*/
@SuppressWarnings("unchecked")
public List<String> extractRoles(String token) {
return extractClaim(token, claims -> (List<String>) claims.get("roles"));
}
/**
* permissions 리스트 추출
*/
@SuppressWarnings("unchecked")
public List<String> extractPermissions(String token) {
return extractClaim(token, claims -> (List<String>) claims.get("permissions"));
}
/**
* 토큰 만료 여부 확인
*/
public boolean isTokenExpired(String token) {
return extractClaim(token, Claims::getExpiration).before(new java.util.Date());
}
/**
* 토큰 유효성 검사 (만료 체크)
*/
public boolean isTokenValid(String token) {
return !isTokenExpired(token);
}
/**
* JWT에서 Claims 추출
*/
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
/**
* JWT 전체 Claims 추출
*/
private Claims extractAllClaims(String token) {
return Jwts.parserBuilder()
.setSigningKey(getSignInKey())
.build()
.parseClaimsJws(token)
.getBody();
}
/**
* Permission Set 변환
*/
@SuppressWarnings("unchecked")
public PermissionSet getPermissions(String token) {
Claims claims = extractAllClaims(token);
List<String> permissions = claims.get("permissions", List.class);
return PermissionParser.parse(permissions);
}
private Key getSignInKey() {
byte[] keyBytes = Decoders.BASE64.decode(secretKey); // auth-service와 동일한 Base64 secret
return Keys.hmacShaKeyFor(keyBytes);
}
public static void main(String[] args) {
JwtService jwtService = new JwtService();
jwtService.secretKey = "D0HaHnTPKLkUO9ULL1Ulm6XDZjhzuFtvTCcxTxSoCS8=";
String token = "eyJhbGciOiJIUzI1NiJ9.eyJmaXJzdE5hbWUiOiJNSVMiLCJsYXN0TmFtZSI6IkNTIiwibG9naW5JZCI6ImNzX21pcyIsInBlcm1pc3Npb25zIjpbIkg6UjpTIiwiQzpDOkEiLCJDOlI6QSIsIkM6VTpBIiwiQzpEOkEiXSwicm9sZXMiOlsiQ1MgU3RhZmYiXSwic3ViIjoiMWU3NTU4YzYtOTFhZC00ZDcxLTg3ZTUtZGJjZmZiYjk5Zjg1IiwiaWF0IjoxNzY0MzQ3Nzg1LCJleHAiOjIwNzk3MDc3ODV9.lL-ZHEpiribxIrNmeYp6LAeU11z-KuRbgELkWjHCCSc";
// user 정보
Claims claims = jwtService.extractAllClaims(token);
System.out.println("Subject (emp_uuid): " + claims.getSubject());
System.out.println("Roles: " + claims.get("roles"));
System.out.println("Roles: " + claims.get("permissions"));
System.out.println("IssuedAt: " + claims.getIssuedAt());
System.out.println("Expiration: " + claims.getExpiration());
System.out.println("FirstName: " + claims.get("firstName", String.class));
System.out.println("LastName: " + claims.get("lastName", String.class));
// 모든 Claims 확인
// Claims claims = Jwts.parserBuilder()
// .setSigningKey(Keys.hmacShaKeyFor("<secret_key>".getBytes()))
// .build()
// .parseClaimsJws(token)
// .getBody();
System.out.println("Claims: " + claims);
}
}