본문 바로가기
제로베이스 BE 21기/Mission

[Reservation] Member 회원가입 & 로그인 기능 구현

by ♡˖GYURI˖♡ 2024. 5. 1.

MemberEntity

MemberEntity는 위와 같이 구성하였다.

memberKey는 Role(권한)을 판단하기 위하여 추가해주었다.

 

BaseEntity도 만들어 extends해주었기에 실제로 Member는 다음과 같이 생성된다.

 

 

Role

Role(권한)은 두 가지가 있다.

  • MANAGER("ROLE_MANAGER")
  • CUSTOMER("ROLE_CUSTOMER")

Role을 반환하는 fromKey 함수는 파라미터로 key를 받아서 권한 타입의 적절성 여부를 판단한다.

    public static Role fromKey(String key) {
        return Arrays.stream(values())
                .filter(o -> o.getKey().equals(key))
                .findFirst()
                .orElseThrow(() -> new CustomException(
                        ErrorCode.INVALID_REQUEST, "잘못된 권한 타입입니다."
                ));
    }

 

 

MemberController

MemberController는 @RequestMapping("/member") 어노테이션을 붙였고, 현재까지는 signUp과 signIn 함수가 구현되어 있다.

 

1. http://localhost:8080/member/signup

SignUpDto를 Body로 받아 ResponseEntity<MemberDto>를 반환한다.

 

SignUpDto에는 회원가입에 필요한 정보만 담도록 하였다. 

  • name
  • email
  • password
  • phone
  • role

MemberDto에는 회원가입 후, 필요한 정보만 담도록 하였다.

  • memberKey
  • name
  • email
  • role

MemberService의 signUp 함수는 다음과 같다.

    @Transactional
    public MemberDto signUp(SignUpDto signUpDto) {
        validateMemberExists(signUpDto.getEmail());

        MemberEntity savedMember = memberRepository.save(
                signUpDto.toEntity(
                        keyGenerator.generateKey(),
                        passwordEncoder.encode(signUpDto.getPassword())
                )
        );

        return MemberDto.fromEntity(savedMember);
    }

 

SignUpDto를 파라미터로 받고, validateMemberExists를 통해 email을 비교하여 이미 회원가입한 이메일인지 여부를 확인한다. 만약 이미 회원가입한 이메일이라면 MEMBER_ALREADY_EXISTS 에러를 throw한다.

 

signUpDto를 MemberEntity로 변환시켜주는 toEntity()는 다음과 같다.

    public MemberEntity toEntity(String memberKey, String password) {
        return MemberEntity.builder()
                .memberKey(memberKey)
                .name(name)
                .email(email)
                .password(password)
                .phone(phone)
                .role(role)
                .build();
    }

 

이 때, memberKey는 keyGenerator.generateKey()로 생성한 키를, password에는 입력받은 password를 passwordEncoder를 통해 encode한 값을 설정해준다.

 

 

2. http://localhost:8080/member/signin

SignInDto를 Body로 받아 ResponseEntity<MemberDto>를 반환한다.

 

SignInDto에는 로그인에 필요한 정보만 담도록 하였다. 

  • email
  • password

MemberService의 signIn 함수는 다음과 같다.  

    public MemberDto signIn(SignInDto signInDto) {
        Authentication authentication = authenticationManagerBuilder.getObject()
                .authenticate(new UsernamePasswordAuthenticationToken(
                        signInDto.email(), signInDto.password()
                ));

        return MemberDto.fromEntity((MemberEntity) authentication.getPrincipal());
    }

 

Spring Security를 사용하여 인증을 처리하고, 인증에 성공한 경우에는 사용자의 정보를 MemberDto로 변환하여 반환하도록 한다.

 

authenticationManagerBuilder.getObject()를 통해 AuthenticationManager를 얻고, 얻어진 AuthenticationManager를 사용하여 UsernamePasswordAuthenticationToken을 생성한다.

이 토큰은 사용자의 아이디와 비밀번호를 나타낸다.

그런 다음 authenticate() 를통해 생성된 토큰을 인증 처리하고, 이 과정에서사용자의 아이디와 비밀번호가 유효한지 확인한다.

인증에 성공하면 Authentication 객체를 반환한다.

 

반환된 Authentication 객체에서 사용자 정보를 추출하여 MemberEntity로 캐스팅하고 MemberDto.fromEntity()를 사용하여 MemberDto로 변환한다.

 

 

Postman 테스트

signup

MANAGER 회원가입
이메일 중복 시
CUSTOMER 회원가입

 

signin

 

정상 로그인
비밀번호가 잘못되었을 경우

 

 

etc

위에 작성한 클래스들에 필요한 기능들을 구현한 클래스들의 목록이다. 

  • SecurityConfig
  • CustomException
  • ErrorCode
  • ErrorResponse
  • GlobalExceptionHandler
  • MemberRepository
  • AuthenticationFilter
  • CustomAccessDeniedHandler
  • CustomAuthenticationEntryPoint
  • TokenProvider
  • CustomUserDetailsService
  • EnumValidator
  • KeyGenerator
  • RoleConverter
  • ValidEnum

 

이 글에 전부 작성하기에는 내용이 많기에 따로 정리할 예정!