_Min 2021. 6. 5. 21:45

회원 엔티티

@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
public class Member{
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="member_id")
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false, unique = true)
    private String nickname;

    @Column(nullable = false, unique = true)
    private String email;

    @Builder.Default
    private String text="";

    @Builder.Default
    private String instaurl="";

    @Builder.Default
    private String twitterurl="";

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String phone;

    @Column(nullable = false)
    private String university;

}

@Builder.Default

Builder 패턴 사용시 기본값으로 null이 들어가는데

@Builder.Default 어노테이션을 사용하면 내가 원하는 값을 default 값으로 설정할 수 있다.

 

@GeneratedValue(strategy = GenerationType.IDENTITY)

현재 연결된 DB에 맞는 Auto Increment 옵션을 추가한다

 

 

회원 리포지토리

import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member, Long> {
    Member findByNickname(String nickname);
    Member findByEmail(String email);
}

JPA 쿼리 메소드라고 해당 방식을 따라 코딩하면 직접 쿼리문을 작성하지 않아도 JPA가 알아서 쿼리문을 날려준다

대충 findByEmail(Stringemail) 이라고 하면 DB email 필드에 String email 값이 있는지 확인해서 값을 반환한다

 

https://arahansa.github.io/docs_spring/jpa.html#jpa.query-methods

자세한 건 위의 링크에서 확인하자

 

 

시큐리티 설정 파일

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity //해당 파일로 시큐리티를 활성화
@Configuration
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder encode(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http); //인증되지 않은 사용자 /login 페이지로 가로채짐(리다이렉트)

        //CSRF 토큰 : 정상적인 사용자인지 아닌지 판단해줌
        http.csrf().disable();
    }


}

인증과 관련된 부분을 처리하는 것으로 보인다

 

 

 

 

회원가입 서비스

import com.post_show_blues.vine.domain.member.Member;
import com.post_show_blues.vine.domain.member.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

//회원가입
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class AuthService {
    private final MemberRepository memberRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * 중복 닉네임 검증
     */
    @Transactional
    public void isDuplicateNickname(String nickname) {
        validateDuplicateMember(nickname);
    }

    /**
     * 회원가입
     */
    @Transactional
    public Member join(Member member) {
        String rawPassword = member.getPassword();
        String encPassword = bCryptPasswordEncoder.encode(rawPassword);
        member.setPassword(encPassword);
        Member memberEntity = memberRepository.save(member);
        return memberEntity;
    }

    /**
     * 전체 회원 조회
     */
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

    private void validateDuplicateMember(String nickname) {
        Member findMember = memberRepository.findByNickname(nickname);
        if (findMember!=null) {
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        }
    }


}

isDuplicateNickname 

UI에 닉네임중복 확인 버튼이 있어 해당 함수를 넣어놨다

 

@Transactional

DB 트랜잭션의 4가지 특성(ACID)는 모두 들어봤을 것이다.

그걸 지켜주기 위한 어노테이션이라고 한다.

DB에 update, delete, insert 연산을 할 때 사용한다

 

.save(), .findAll()

리포지토리에서 JpaRepository<Member, Long>을 상속하면 자동으로 사용가능한 메소드들이다

 

BCryptPasswordEncoder

DB에 비밀번호 삽입할 때 해당 라이브러리로 암호화해서 넣지 않으면 나중에 로그인 진행할 때 오류가 생긴다.

해당 라이브러리가 비밀번호를 SpringSecurity에서 원하는 패턴으로 암호화해주는 걸로 보인다.

 

 

회원가입 Dto

import com.post_show_blues.vine.domain.member.Member;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.validation.constraints.NotEmpty;


@Getter
@Setter
@Builder
@ToString
public class SignupDto {
    @NotEmpty
    private String name;
    @NotEmpty
    private String nickname;
    @NotEmpty
    private String email;
    @NotEmpty
    private String password;
    @NotEmpty
    private String phone;
    @NotEmpty
    private String university;

    public Member toEntity() {
        return Member.builder()
                .name(name)
                .nickname(nickname)
                .password(password)
                .email(email)
                .phone(phone)
                .university(university)
                .build();
    }
}

@NotEmpty

controller에서 @Valid 어노테이션을 붙여주면 Dto와 값을 매핑할 때 값이 유효한지 판단해준다 

현재 모든 필드에 값을 받고 싶어서 @NotEmpty를 다 붙여주었다.

 

 

 

테스트

import com.post_show_blues.vine.domain.member.Member;
import com.post_show_blues.vine.domain.member.MemberRepository;
import com.post_show_blues.vine.dto.Auth.SignupDto;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertThrows;

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class AuthServiceTest {
    @Autowired AuthService authService;
    @Autowired MemberRepository memberRepository;

    @Test
    public void 중복닉네임() throws Exception {
        //given
        SignupDto memberEntityA = createSignupDto();

        String nickname="memberNickname";

        //when
        Member memberA = authService.join(memberEntityA.toEntity());

        //then
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> authService.isDuplicateNickname(nickname));

        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");

    }

    @Test
    public void 회원가입() throws Exception {
        //given
        SignupDto memberEntityA = createSignupDto();


        //when
        Member memberA = authService.join(memberEntityA.toEntity());

        //then
        assertThat(memberA.getNickname()).isEqualTo(memberEntityA.getNickname());

    }

    SignupDto createSignupDto(){
        return SignupDto.builder()
                .name("memberA")
                .email("member@duksung.ac.kr")
                .nickname("memberNickname")
                .password("1111")
                .phone("010-0000-0000")
                .university("덕성대학교")
                .build();
    }



}

Assertions.assertThat(a).isEqualTo(b)

a와 b가 같은지 검증한다

 

 

 

성공

 

 

 

 

코드 깃헙 주소 https://github.com/JMine97/vine

참고 강의 https://www.easyupclass.com/course/218/about

728x90