(OAuth2 Login) 구글 소셜 로그인 구현 (2) - 도메인 생성
Spring Security + JWT를 이용한 소셜 로그인 구현
도메인 생성
BaseTime
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTime {
@CreatedDate
private LocalDateTime createdDate; // 생성시간
@LastModifiedDate
private LocalDateTime updatedDate; // 수정시간
}
- User가 생성되거나 변경될 때의 시간을 추가적으로 저장하기 위해서 BaseTime을 생성한다.
@CreateDate
로 User가 생성되는 시간을 나타내는 필드를 지정한다.-
@LastModifiedDate
로 User가 변경되는 시간을 나타내는 필드를 지정한다. ``` @SpringBootApplication @EnableJpaAuditing public class AppApplication {public static void main(String[] args) { SpringApplication.run(AppApplication.class, args); }
}
- BaseTime을 적용하기 위해서는 AppApplication 클래스에 `@EnableJpaAuditing`을 추가해주어야한다.
<br>
### Role
@Getter @RequiredArgsConstructor public enum Role {
GUEST("ROLE_GUEST"), USER("ROLE_USER");
private final String key; } ``` - 회원가입(추가정보 입력)을 하지 않는 최초 로그인 사용자를 나타내는 GUEST와 이외의 로그인 사용자를 나타내는 USER를 구분하기 위해서 ENUM을 생성한다.
User Entity
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor
public class User extends BaseTime {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String socialId;
private String name;
private String nickname;
private String email;
private String imageUrl;
private String refreshToken;
// 최초 로그인 구분, GUEST, USER
@Enumerated(EnumType.STRING)
private Role role;
private String state;
private String description;
private String interest;
public void authorizeUser() {
this.role = Role.USER;
}
public void updateRefreshToken(String updateRefreshToken) {
this.refreshToken = updateRefreshToken;
}
public void signUp(String nickname, String imageUrl) {
this.nickname = nickname;
this.imageUrl = imageUrl;
}
public void logout() {
this.refreshToken = null;
}
- 사용자의 정보를 가지고 있는 User Entity를 생성한다.
- role 필드를 통해 사용자를 구분한다.
- 구글로부터 socialId, name, email을 받아와 저장한다.
- 회원가입을 통해 imageUrl, nickname을 저장한다.
- refresh 토큰을 DB에 저장하기 위해서 refreshToken 필드를 추가한다.
User Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findBySocialId(String socialId);
Optional<User> findByNickname(String nickname);
Optional<User> findByRefreshToken(String refreshToken);
Optional<User> findByEmail(String email);
}
- 찾을 사용자가 존재할 수도, 존재하지 않을 수도 있기 때문에 모든 메서드를 Optional
타입으로 선언하였다. - 다양한 필드를 통해 해당 USER를 찾을 수 있도록 메서드를 추가하였다.
USER DTO
public record UserSignupJsonRequest(String nickname) {
}
- 회원가입을 통해 사용자의 닉네임을 클라이언트로부터 받아오기 위해 UserSignupJsonRequest 레코드를 생성하였다.
public record UserSignupRequest(
String nickname,
MultipartFile image
) {
public static UserSignupRequest of(UserSignupJsonRequest request, MultipartFile image) {
return new UserSignupRequest(request.nickname(), image);
}
}
- 회원가입을 통해 사용자의 닉네임 정보를 담은 UserSignupJsonRequest 객체와 이미지를 받아 인스턴스를 생성하는 UserSignupRequest 레코드를 생성하였다.