카테고리 없음

스프링 시큐리티를 이용한 회원가입과 로그인 2 - 엔티티, 회원가입로직

근즈리얼 2021. 10. 1. 19:51
728x90

저번 포스팅에서 개발을 막는 스프링 시큐리티를 일시적으로 멈췄으니 본격적으로 개발을 해보겠습니다.

 

사실 오늘 포스팅 내용은 시큐리티와는 관련이 없습니다.... ㅎㅎ

 

우선 오늘 포스팅의 순서를 정하겠습니다.

1. enum : member의 필드중 enum값이 있기 때문에 enum을 먼저 만들겠습니다.

2. member : member 엔티티를 만들어 줍니다.

3. memberDto : 회원가입을 위한 dto를 만들어 줍니다.

4. memberRepository

5. memberService : 여기에 회원가입 로직이 만들어집니다.

6. test : 회원가입 로직이 잘 만들어졌는지 확인해봅니다.

 

위의 순서대로 완성하면 아래 사진과 같은 구조를 갖게 됩니다.

 

Role enum 코드

package com.asdanything.ask.constant;

public enum Role {
    USER, ADMIN
}

저는 유저와 관리자 권한만 생각했기 때문에 두 가지 특성만 만들었습니다.

 

member 코드

package com.asdanything.ask.Entity;

import com.asdanything.ask.constant.Role;
import com.asdanything.ask.dto.MemberFormDto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.persistence.*;

@Entity
@Table(name = "member")
@Getter
@Setter
@ToString
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

	@Column(unique = true)
    private String email;

    private String name;

    private String password;

    @Enumerated(EnumType.STRING) // 데이터베이스에 저장할 때 enum을 USER 또는 ADMIN으로 저장한다.
    private Role role;

    public static Member createMember(MemberFormDto memberFormDto, PasswordEncoder passwordEncoder){
        String enPassword = passwordEncoder.encode(memberFormDto.getPassword());
        Member member = new Member();
        member.setName(memberFormDto.getName());
        member.setEmail(memberFormDto.getEmail());
        member.setPassword(enPassword);
        member.setRole(Role.USER);

        return member;
    }
}

- 데이터베이스에 저장하기 위한 id값, email, name, password와 role값만 필요합니다.

- dto와 passwordEncoder를 이용하여 member를 만드는 메소드를 만들었습니다.

- passwordEncoder는 SecurityConfig에서 빈으로 등록했습니다.

 

memberFormDto 코드

package com.asdanything.ask.dto;

import lombok.Data;

@Data
public class MemberFormDto {

    private String name;
    private String email;
    private String password;
}

- name, email, password 의 데이터만 필요하기 때문에 Dto는 이렇게 만들었습니다.

 

memberRespository 코드

package com.asdanything.ask.repository;

import com.asdanything.ask.Entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member,Long> {

    Member findByEmail(String email);
}

 

memberService 코드

package com.asdanything.ask.service;

import com.asdanything.ask.Entity.Member;
import com.asdanything.ask.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;

    public Member saveMember(Member member){

        checkDuplication(member);
        return memberRepository.save(member);
    }

    private void checkDuplication(Member member) {
        Member findMember = memberRepository.findByEmail(member.getEmail());
        if(findMember != null){
            throw new IllegalStateException("이미 가입된 회원입니다.");
        }
    }
}

- 우선 memberRepository가 필요하기 때문에 필드 값으로 불러옵니다.

- saveMember메소드를 사용하면 먼저 checkDuplication메소드를 실행합니다.

- checkDuplication 메소드는 넘어온 member데이터의 email값을 기준으로 데이터베이스에서 Member를 찾아옵니다.

- null값이라면 데이터베이스에 저장된 값이 없으므러 처음 회원가입하는 email이 맞지만 null이 아니라면 같은 이메일의 Member가 있다는 뜻이됩니다.

- 따라서 IllegalStateException을 발생시켜줍니다.

- checkDuplication에서 문제없이 잘 실행됐다면 saveMember 메소드로 돌아와 데이터베이스에 잘 저장하면 됩니다.

 

마지막으로 항상 프로젝트를 진행할 때 하고 싶었던 방법이지만 못했던 test코드를 만들어 보겠습니다.

 

memberService에 alt + enter를 누르면 create test가 뜹니다 이때 생성을 눌러주면

이렇게 만들어진 것을 볼 수 있습니다.

 

test 코드입니다

package com.asdanything.ask.service;

import com.asdanything.ask.Entity.Member;
import com.asdanything.ask.dto.MemberFormDto;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@Transactional
class MemberServiceTest {

    @Autowired
    MemberService memberService;

    @Autowired
    PasswordEncoder passwordEncoder;

    public Member createMember(){
        MemberFormDto memberFormDto = new MemberFormDto();
        memberFormDto.setEmail("asd@asd.com");
        memberFormDto.setName("asd");
        memberFormDto.setPassword("1234");
        return Member.createMember(memberFormDto,passwordEncoder);
    }

    @Test
    @DisplayName("회원가입 성공 테스트")
    public void 회원가입(){
        Member member = this.createMember();
        Member saveMember = memberService.saveMember(member);

        assertEquals(member.getEmail(),saveMember.getEmail());
        assertEquals(member.getName(),saveMember.getName());
    }

    @Test
    @DisplayName("회원가입 중복 테스트")
    public void 중복회원가입(){
        Member member1 = createMember();
        Member member2 = createMember();

        memberService.saveMember(member1);

        Throwable e = assertThrows(IllegalStateException.class, () -> memberService.saveMember(member2));

        assertEquals("이미 가입된 회원입니다.", e.getMessage());
    }

}
728x90