24.08.27

윤지현·2024년 8월 27일

TIL

목록 보기
51/75

오늘의 루틴

  • 개인과제 7단계 완료 및 8~9단계 시도 (O)
  • 공부한 내용 복습 (O)

한 번 추가 구현 단계도 도전을 했다. 7단계를 하려면 jwt를 해야한다.

  • 7단계 : 회원가입

🔻 조건

  • 유저에 비밀번호 필드를 추가합니다.
    • 비밀번호는 암호화되어야 합니다.
    • 암호화를 위한 PasswordEncoder를 직접 만들어 사용합니다.
  • 유저 최초 생성(회원가입) 시 JWT를 발급 후 반환합니다.

일단 build.gradle에 라이브러리를 추가해야한다.


1. build.gradle

    implementation 'at.favre.lib:bcrypt:0.10.2'

    // JWT
    compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'

비밀번호를 암호화 할 PasswordEncoder와 jwt를 생성할 JwtUtil를 생성한다.


1. PasswordEncoder.java

@Component
public class PasswordEncoder {

    public String encode(String rawPassword) {
        return BCrypt.withDefaults().hashToString(BCrypt.MIN_COST, rawPassword.toCharArray());
    }

    public boolean matches(String rawPassword, String encodedPassword) {
        BCrypt.Result result = BCrypt.verifyer().verify(rawPassword.toCharArray(), encodedPassword);
        return result.verified;
    }
}

2.JwtUtil.java

jwt를 생성할 createToken 메서드

public static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String BEARER_PREFIX = "Bearer ";
    private final long TOKEN_TIME = 60 * 60 * 1000L; // 60분

    @Value("${jwt.secret.key}")
    private String secretKey;
    private Key key;
    private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

    public static final Logger logger = LoggerFactory.getLogger("JWT 관련 로그");

    @PostConstruct
    public void init() {
        byte[] bytes = Base64.getDecoder().decode(secretKey);
        key = Keys.hmacShaKeyFor(bytes);
    }

    public String createToken(String username) {
        Date date = new Date();

        return BEARER_PREFIX +
                Jwts.builder()
                        .setSubject(username)
                        .setExpiration(new Date(date.getTime() + TOKEN_TIME))
                        .setIssuedAt(date)
                        .signWith(key, signatureAlgorithm)
                        .compact();
    }

jwt가 생성하면 앞에 'bearer '를 분리할 substringToken 메서드

    public String substringToken(String tokenValue) {
        if (StringUtils.hasText(tokenValue) && tokenValue.startsWith(BEARER_PREFIX)) {
            return tokenValue.substring(7);
        }
        logger.error("Not Found Token");
        throw new NullPointerException("Not Found Token");
    }

jwt를 검증할 validateToken 메서드

public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
            return true;
        } catch (SecurityException | MalformedJwtException | SignatureException e) {
            logger.error("Invalid JWT signature, 유효하지 않는 JWT 서명 입니다.");
        } catch (ExpiredJwtException e) {
            logger.error("Expired JWT token, 만료된 JWT token 입니다.");
        } catch (UnsupportedJwtException e) {
            logger.error("Unsupported JWT token, 지원되지 않는 JWT 토큰 입니다.");
        } catch (IllegalArgumentException e) {
            logger.error("JWT claims is empty, 잘못된 JWT 토큰 입니다.");
        }
        return false;
    }

입력 받을 user의dto와 user 엔티티를 수정한다.


1. User.java

비밀번호를 입력할 password 필드를 추가

@Column(name = "password", nullable = false)
    private String password;

비밀번호 추가

    public User(String username, String email, String password) {
        this.username = username;
        this.email = email;
        this.password = password;
    }

2. UserRequestDtojava

@Getter
public class UserRequestDto {
    private String username;
    private String password;
    private String email;
}

3. UserResponseDto.java

@Getter
public class UserResponseDto {
    private Long id;
    private String username;
    private String email;
    private String token;
    private LocalDateTime createdAt;
    private LocalDateTime modifiedAt;

    public UserResponseDto(User user) {
        this.id = user.getId();
        this.username = user.getUsername();
        this.email = user.getEmail();
        this.createdAt = user.getCreatedAt();
        this.modifiedAt = user.getModifiedAt();
    }

    public UserResponseDto(User user, String token) {
        this.id = user.getId();
        this.username = user.getUsername();
        this.email = user.getEmail();
        this.token = token; // Set token
        this.createdAt = user.getCreatedAt();
        this.modifiedAt = user.getModifiedAt();
    }
}

또한 UserService에서 일정을 생성할 때 JWT를 생성할 코드 추가


1. UserService.java

JWT 생성 코드 추가

// JWT 생성
        String token = jwtUtil.createToken(user.getUsername());

이러면 유저를 생성할 때 JWT도 생성된다.

profile
첫 시작

0개의 댓글