서버의 HTTPS설정은 서버에서 데이터 전송 과정에 누군가 데이터를 가로채 볼 수 없도록 보호하는 수단이다.
하지만 이것은 서버의 통신이 안전한 것이지, 서버가 안전하다는게 아니다.
만약 Client에서 비밀번호와같은 개인정보를 서버에서 전송했는데, 이러한 개인정보를 DB에 저장해두었다면,
그 DB가 노출된다면 개인정보가 노출되는 것이다... 😬
그래서 JWT(JSON Web Token)을 이용하여 데이터를 암호화 할 것이다.
JWT는 Base64 URL 인코딩을 사용하여 토큰의 내요을 암호화하고 서명하여 인증 및 권한부여를 해준다.
JWT는 서명을 통해 서버에서 검증 과정을 거쳐 변조가 되었는지 확인할 수 있으며, 만료 시간을 설정하여 토큰의 악용을 막을 수 있다.
보통 AccessToken과 RefreshToken으로 나뉘는데, 자세한 내용은 다음에 포스팅 하겠다.
public class JwtUtil {
Long exp = 3600000L; // 1시간(3600000밀리초)
private static final String SECRET_KEY = "SecretKey"; // JWT를 암호화하기 위한 Secret Key
public static String generateToken(String subject, long ttlMillis) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
// JWT 토큰 생성
String token = Jwts.builder()
.setSubject(subject) //subject 설정
.setIssuedAt(now) //토큰이 발급된 시간
.setExpiration(new Date(nowMillis + exp)) //유효기간 설정
.signWith(SignatureAlgorithm.HS256, SECRET_KEY) //서명
.compact(); //합치기
return token;
}
exp는 토큰의 만료시간이다. accessToken, refreshToken 등 용도에 따라 다르게 설정해야 한다.
만료시간이 길수록 탈취당할 확률이 높아진다.
따라서 짧은 인증을 요구할 때에는 짧은 만료시간을 두는게 좋다.
public static boolean validateToken(String token) {
try {
// JWT 토큰 파싱
Claims claims = Jwts.parserBuilder()
.setSigningKey(KEY)
.build()
.parseClaimsJws(token)
.getBody();
return true;
} catch (Exception ex) {
return false;
}
}
토큰이 유효한지 검사하는 로직이다. 설정해둔 KEY를 통해 토큰을 파싱하고 유효한 토큰이면 true, 유효하지 않으면 false를 반환한다.
public static Claims getJwtBody(String token) {
// JWT 토큰 파싱
Claims claims = Jwts.parserBuilder()
.setSigningKey(KEY)
.build()
.parseClaimsJws(token)
.getBody();
return claims;
}
토큰 내에 Body값을 가져오려면, SignKey를 통해 파싱하고 getBody()를 사용한다.