본문 바로가기
공부/Spring

[Spring] 스프링 jwt 생성, 검증, 값 가져오기 구현

by 웅대 2023. 4. 30.
728x90
반응형

로그인한 회원임을 인증하기 위해서 토큰 방식이 주로 쓰이곤한다.

 

로그인에 성공하면 서버에서 토큰을 클라이언트에게 넘겨준다.

 

그리고 로그인이 필요한 요청을 할 때마다 요청 헤더에 토큰을 담아서 서버에 보내준다.

 

서버에서는 받은 토큰의 유효성 검사를 실시하고 유효하다면 올바른 데이터를 반환해주고 유효하지 않다면 unauthorized 에러를 반환한다.

 

토큰의 경우 json web token(jwt)를 주로 사용한다.

 

이 jwt를 발급하는 과정을 포스팅 해보려고 한다.

 

먼저 build.gradle의 dependencies에 다음 코드를 추가한다.

implementation 'io.jsonwebtoken:jjwt:0.9.1'

그리고 토큰 생성에 사용될 secretKey와 유효 기간을 만들어야한다.

 

secretKey와 유효기간은 application.yml 파일 안에 보관할 에정이다.

 

resources 폴더 안에 application.properties 안에 secretKey와 유효 기간을 만든다.

jwt.secretKey=jwtPractice
jwt.expiredMs=60000

기본 단위는 ms이고 테스트를 위해 1분으로 짧게 설정했다.

 

간단한 사용법을 위한 포스팅이라 짧게 정했지만 실제 프로젝트를 진행할 때는 길게 하는 편이 좋을 듯 하다.

 

이제 jwt 생성 및 검증에 관련한 JwtUtil 클래스를 만들 차례이다.

 

util 패키지를 생성하고 그 안에 JwtUtil 클래스를 생성한다.

 

JwtUtil 안에 createJwt 라는 static 메소드를 만든다. 여기서 토큰을 생성하여 반환할 것이다.

 

jwt를 생성할 때 필요한 정보는 다음 3가지를 넣을 예정이다.

 

  1. 생성 날짜
  2. 만료 날짜
  3. 해시 알고리즘

createJwt

    public static String createJwt(String secretKey, Long expiredMs, String memberEmail) {
        Claims claims = Jwts.claims();
        claims.put("email", memberEmail);

        String token = Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expiredMs))
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
        return token;
    }

가장 처음에 Claims 인스턴스를 생성하는 모습을 볼 수 있다.

 

Claims에 원하는 정보를 key-value 쌍으로 담고 토큰을 만들 때 넣어주면 나중에 꺼낼 수 있다.

 

토큰의 주체를 확인하기 위해 unique한 값인 email을 넣어주었다.

 

getMemberEmail

위에서 claims에 이메일을 넣어주었고 claims을 넣은 token을 client에게 반환하면 client는 인증이 필요할 때마다 토큰 값을 같이 보내줄 것이다.

 

서버에서는 토큰의 유효성을 검사하고 유효하다면 unique한 값인 memberEmail을 바탕으로 Repository에서 해당 유저의 정보를 가지고 올 수 있다.

 

이를 위한 함수가 getMemberEmail 함수이다.

public static String getMemberEmail(String token, String secretKey) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token)
                .getBody().get("email", String.class);
    }

 

다음은 jwt가 만료되었는지 체크하는 메소드이다.

isExpired

public static boolean isExpired(String token, String secretKey) {
    return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token)
            .getBody().getExpiration().before(new Date());
}
secretKey와 token을 넣어주고 만료 날짜가 지나지 않았으면 True, 지났으면 False를 반환한다.

 

모든 함수는 바로 사용할 수 있도록 static으로 만들어두었다.

 

<JwtUtil.java> 전체 코드

public class JwtUtil {
    public static String getMemberEmail(String token, String secretKey) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token)
                .getBody().get("email", String.class);
    }
    public static boolean isExpired(String token, String secretKey) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token)
                .getBody().getExpiration().before(new Date());
    }
    public static String createJwt(String secretKey, Long expiredMs, String memberEmail) {
        Claims claims = Jwts.claims();
        claims.put("email", memberEmail);

        String token = Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expiredMs))
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
        return token;
    }
}

다음 포스팅에서는 Spring Security를 활용해서 jwt를 발급해보고 인증, 인가도 구현해보려고 한다.

728x90
반응형

댓글