본문 바로가기
카테고리 없음

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

by 근즈리얼 2021. 10. 1.
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

댓글