본문 바로가기
개발

JWT 활용한 로그인 구현 - 1

by 공덕뉸나 2023. 8. 30.

프로젝트를 진행할 때 나는 회원 관련 기능들이 가장 까다로웠다.

Token을 사용하고 Spring Security를 사용하고 비밀번호랑 휴대폰번호를 암호화하는 과정들에서 설정할 게 너무 많게 느껴졌다.

그 전에는 Java11과 SpringBoot2 버전을 사용했는데 버전을 다 올려서 개발하다보니 deprecated 된 것들이 많아서 찾아보는데 이전 버전에 관련된 글들이 많아 구글링하는 것도 좀 어려웠다.. 

실무를 하면서 개발했던거랑 코틀린을 사용해서 개발했던거랑 이번에 개발하는거랑 방식이 조금씩 다 달라서 어떤게 바뀌었는지 파악하는게 중요함을 다시 한 번 깨달았다.

 

사실 회원가입, 로그인 구현을 여러 번 해보았지만 할 때마다 어렵다고 느껴 이번에도 실무할 때 개발했던 것을 참고하고, 구글링하면서 개발했는데 모르는 부분이 많아 학습했고 정리가 필요할 것 같아서 포스팅 하기로 마음 먹었다.

 

이전에 User 엔티티를 생성할 때는 필요없다고 생각했는데 로그인 기능을 구현하다보니 관리자 계정이랑 일반 사용자 계정이랑 분리하는게 좋을 것 같다는 생각이 들어서 UserRole 필드를 하나 추가했다.

 

엔티티

 

Users.java

@JsonIgnore
@Builder.Default
@OneToMany(fetch = FetchType.LAZY, mappedBy = "users", 
cascade = CascadeType.ALL,orphanRemoval = true)
private List<UserRoles> userRoles = new ArrayList<>();

@Builder.Default : 특정 필드를 특정 값으로 초기화하고 싶을 때 사용

@OneToMany

- CascadeType.ALL : 사용자가 생성되거나 삭제되면 같이 생성되거나 삭제되어야 한다.

- orphanRemoval = true : 부모 엔티티와 자식 엔티티의 연관관계가 끊어졌을 경우, 자식 엔티티를 모두 제거

 

UserRoles.java

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(indexes = {@Index(columnList = "userId, userRole", unique = true)})
public class UserRoles extends BaseEntity implements Serializable {

    @Serial
    private static final long serialVersionUID = 5964759107958368227L;

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @Column(columnDefinition = "varchar(36) COMMENT 'UserRole Id'")
    private String userRoleId;

    @Column(columnDefinition = "bigint COMMENT '회원 ID'", insertable = false, updatable = false)
    private Long userId;

    @Setter
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "userId", referencedColumnName = "userId")
    private Users users;

    @Column(columnDefinition = "varchar(20) COMMENT '권한'")
    @Enumerated(EnumType.STRING)
    private UserRole userRole;

    public static UserRoles makeUserRole(UserRole role){
        return UserRoles.builder().userRole(role).build();
    }

}

UserRole Enum에는 ROLE_MASTER, ROLE_USER를 넣었다.

 

gradle 추가

 

로그인 기능을 사용하려면 dependency를 여러개 추가해야했다.

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.2'
implementation 'com.sun.xml.bind:jaxb-impl:4.0.1'
implementation 'com.sun.xml.bind:jaxb-core:4.0.1'
implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'

내가 알기로는 위 두 개만 추가하면 됐었는데 로그인 API를 구현하고 테스트 해보니 500에러가 떴다.

java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter

이런 에러였는데 찾아보니 build.gradle을 이용해 JWT 토큰을 생성할 때 에러가 발생하면서 토큰이 생성되지 않는 것이었다.

그래서 밑의 디펜던시를 추가해 준 뒤 테스트를 다시 해보니 정상적으로 토큰이 생성되었다.

 

내용이 너무 길어질 것 같아 다음 글에서 이어서 써야겠다.

다음에는 config, util, security 등 로그인 기능에 필요한 설정들에 대해 차근차근 정리해봐야겠다. 망망!

 

'개발' 카테고리의 다른 글

JWT 활용한 로그인 구현 - 3  (0) 2023.09.01
JWT 활용한 로그인 구현 - 2  (0) 2023.08.31
Enum 생성  (1) 2023.08.23
BaseEntity 생성하기  (0) 2023.08.19
엔티티 생성  (0) 2023.08.18