프로젝트를 진행할 때 나는 회원 관련 기능들이 가장 까다로웠다.
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 |