2 회원가입
회원 엔티티
@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