메인 프로젝트를 하면서 REST API로 로그인을 구현해보았다.
해당 부분을 기억하기 위해 이 글을 작성하였다.
이 포스팅은 프로젝트 과정에서 흐름을 기억하기 위해 작성한 것으로, 기본 흐름의 틀정도라고 생각하면 좋을 듯 하다.
해당 포스팅의 코드는 아래의 깃헙 주소에서도 확인 가능.
로그인 구현인데 회원 로직 구현인 이유?
: 회원 기본 로직이 구현 되어야 로그인 구현이 가능하기 때문
1️⃣ 공통의 Member 엔티티 구현
- 공통의 회원 클래스인 Member 엔티티 구현
- 메인 프로젝트에서 회원을 소비자와 생산자로 나누어 관리
- 공통의 회원 클래스를 두고, 소비자와 생산자를 나누었음.
@Getter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberId;
@Column(length = 45, nullable = false)
private String name;
@Column(length = 45, nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(length = 50, nullable = false)
private String phone;
@Column(length = 100, nullable = false)
private String address;
/* 소셜 로그인 아이디 추가 */
@Column
private String socialId;
/* 소셜 로그인을 추가하면서 해당 판별을 위한 프로바이더 타입 추가 */
@Enumerated(EnumType.STRING)
private ProviderType providerType;
/* Authority 로 일일히 확인하기 어려우니 컬럼 추가 */
@Column
private String role;
/* security 이용하여 역할 추가 */
@ElementCollection(fetch = FetchType.EAGER)
private List<String> roles;
/* 💜 소비자 - 회원 일대일 연관 관계 : 회원 참조*/
@OneToOne(mappedBy = "member", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private Client client;
/* 💜소비자 - 회원 연관 관계 편의 메서드 */
public void setClient(Client client) {
this.client = client;
if (client.getMember() != this) {
client.setMember(this);
}
}
/* 💚 판매자 - 회원 일대일 연관 관계 : 회원 참조 */
@OneToOne(mappedBy = "member", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private Seller seller;
/* 💚 판매자 - 회원 연관 관계 편의 메서드 */
public void setSeller(Seller seller) {
this.seller = seller;
if (seller.getMember() != this) {
seller.setMember(this);
}
}
public Member(String name, String email, String password,
ProviderType providerType, String role, List<String> roles, String socialId) {
this.name = name;
this.email = email;
this.password = password;
this.providerType = providerType;
this.role = role;
this.roles = roles;
this.socialId = socialId;
}
public void setCreateMember(String password, String role, List<String> roles, ProviderType providerType) {
this.password = password;
this.role = role;
this.roles = roles;
this.providerType = providerType;
}
}
2️⃣ Seller, Client 엔티티 클래스 구현
- 나누어 관리할 소비자와 생산자 엔티티 클래스 구현
@Getter
@Entity
@NoArgsConstructor
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long clientId;
/* 💜소비자 - 회원 일대일 연관 관계 : 회원 참조*/
@OneToOne
@JoinColumn(name = "member_id")
private Member member;
/* 💜소비자 - 회원 연관 관계 편의 메서드 */
public void setMember(Member member) {
this.member = member;
if (member.getClient() != this) {
member.setClient(this);
}
}
}
@Getter
@Entity
@NoArgsConstructor
public class Seller {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long sellerId;
@Column
private String introduce;
@Column
private String imageUrl;
/* 💚 판매자 - 회원 일대일 연관 관계 : 회원 참조 */
@OneToOne
@JoinColumn(name = "member_id")
private Member member;
/* 💚 판매자 - 회원 연관 관계 편의 메서드 */
public void setMember(Member member) {
this.member = member;
if (member.getSeller() != this) {
member.setSeller(this);
}
}
@Builder
public Seller(Long sellerId, String introduce, String imageUrl) {
this.sellerId = sellerId;
this.introduce = introduce;
this.imageUrl = imageUrl;
}
}
3️⃣ MemberRepository 구현
- 회원 CRUD를 위한 Repository 클래스 구현
@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findByEmail(String email);
}
4️⃣ MemberMapper 구현
- DTO 변환을 위한 Mapper 클래스 구현
@Mapper(componentModel = "spring")
public interface MemberMapper {
default Member memberPostDtoToMember(MemberDto.Post post) {
if (post == null) {
return null;
}
Member.MemberBuilder member = Member.builder();
member.name( post.getName() );
member.email( post.getEmail() );
member.password( post.getPassword() );
member.phone( post.getPhone() );
member.address( post.getAddress() );
member.role( post.getRole() );
return member.build();
}
default MemberDto.ClientResponseDto memberToClientResponseDto(Member member) {
if (member == null) {
return null;
}
MemberDto.ClientResponseDto response =
MemberDto.ClientResponseDto.builder()
.memberId(member.getMemberId())
.clientId(member.getClient().getClientId())
.email(member.getEmail())
.name(member.getName())
.phone(member.getPhone())
.address(member.getAddress())
.role(member.getRole())
.build();
return response;
}
default MemberDto.SellerResponseDto memberToSellerResponseDto(Member member) {
if (member == null) {
return null;
}
MemberDto.SellerResponseDto response =
MemberDto.SellerResponseDto.builder()
.memberId(member.getMemberId())
.sellerId(member.getSeller().getSellerId())
.email(member.getEmail())
.name(member.getName())
.phone(member.getPhone())
.address(member.getAddress())
.role(member.getRole())
.introduce(member.getSeller().getIntroduce())
.imageUrl(member.getSeller().getImageUrl())
.build();
return response;
}
}
'Spring' 카테고리의 다른 글
[Spring] 로그인 구현 3 - 카카오 로그인 구현 (1) | 2022.12.20 |
---|---|
[Spring] 로그인 구현 2 - 회원 가입 & 자체 로그인 구현 (1) | 2022.12.20 |
[Spring] Transaction (0) | 2022.12.19 |
[Spring] JDBC와 Spring JDBC, Spring Data JDBC, Spring Data JPA (0) | 2022.12.17 |
[Spring] Spring boot Java 카카오 페이 단건 결제 구현하기 (0) | 2022.12.08 |
댓글