본문 바로가기

SPRING-SECURITY

JWT + OAuth2 구현 - (2)

Member 도메인

Member

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member extends Auditable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long memberId;

    @Column
    private String name;

    @Column
    private String email;

    @Column
    private String password;

    @OneToMany(mappedBy = "member")
    private List<Board> boardList = new ArrayList<>();

    @OneToMany(mappedBy = "member")
    private List<Comment> commentList = new ArrayList<>();

    @Enumerated(EnumType.STRING)
    private Role role;//ROLE_USER, ROLE_ADMIN

    @Enumerated(EnumType.STRING)
    private SocialType socialType;//GOOGLE,NAVER,KAKAO

    private String refreshToken; // 리프레시 토큰

    public void setRole(Role role) { //삭제예정
        this.role = role;
    }

    @Builder
    public Member(String name, String email, String password, List<Board> boardList, List<Comment> commentList,Role role) {

        this.name = name;
        this.email = email;
        this.password = password;
        this.boardList = boardList;
        this.commentList = commentList;
        this.role = role;
    }

    public void updateRefreshToken(String updateRefreshToken) {
        this.refreshToken = updateRefreshToken;
    }
}

SocialType은 추후에 적용할 Oauth2를 위해 추가해줬고

@Setter를 사용하지 않기 위해 Builder를 이용했다.

로그인 성공 시 AccessToken과 RefreshToken을 발행하는데 이것을 entity에 저장할 예정

 

updateRefreshToken은 일단 엔티티에 작성 해 놨는데 다른 곳에 위치하는게 이상적이라면 옮길 생각이다.

 

Role

@Getter
public enum Role {
    USER, ADMIN
}

권한 관련 Enum 파일이다.

기본적으로 내 개인 블로그기 때문에 내 계정만 ADMIN 권한으로 생성할 생각이고

나머지 계정들은 USER로 DB에 적용할 생각

 

MemberRepository

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {

    Optional<Member> findByEmail(String email);

    Optional<Member> findByRefreshToken(String refreshToken);


//    Optional<Member> findBySocialTypeAndSocialId(SocialType socialType, String socialId);
}

 

MemberDto

public class MemberDto {

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Post {
        @NonNull
        @Pattern(regexp = "^[a-zA-Z0-9+.-]+@[a-zA-Z0-9.-]+$")
        private String email;
        @NonNull
        @Pattern(regexp = ".{8,}")
        private String password;
        @NonNull
        @Pattern(regexp = ".{2,}")
        private String name;
    }

    @Getter
    @AllArgsConstructor
    public static class Response {
        private long memberId;
        private String name;
        private String email;
        private LocalDateTime createdAt;
        private LocalDateTime modifiedAt;
    }
}

 

MemberService

@Slf4j
@Transactional
@RequiredArgsConstructor
@Service
public class MemberService {

    private final MemberRepository memberRepository;
    private final PasswordEncoder passwordEncoder;

    public Member createMember(Member member) {

        //Email 중복 검사
        Boolean newEmail = checkEmail(member.getEmail());
        if (!newEmail) {
            throw new BusinessException(ExceptionCode.EMAIL_EXISTS);
        }
        //비밀번호 암호화
        String encryptedPassword = passwordEncoder.encode(member.getPassword());
        //객체 생성
        Member newMember = Member.builder()
                .name(member.getName())
                .email(member.getEmail())
                .password(encryptedPassword)
                .role(Role.USER)
                .build();
        //ORM을 사용해 생성된 객체 DB에 저장
        return memberRepository.save(newMember);
    }

    //Email 중복 검사
    private Boolean checkEmail(String email) {
        Optional<Member> optionalMember = memberRepository.findByEmail(email);
        return optionalMember.isEmpty();
    }


}

checkEmail같은 검증 메소드가 추후 프로젝트 진행하면서 많아진다면 클래스를 하나 따로 뺄 생각이지만 현재 상황에선 굳이 그럴 필요는 없을것같다.

 

MemberController

@Slf4j
@RequiredArgsConstructor
@RequestMapping("/members")
@RestController
public class MemberController {

    private final MemberService memberService;
    private final MemberMapper memberMapper;

    //회원가입
    @PostMapping("/signup")
    public ResponseEntity postMember(@Valid @RequestBody MemberDto.Post memberPostDto) {
        Member member = memberMapper.memberPostToMember(memberPostDto);
        Member savedMember = memberService.createMember(member);
        MemberDto.Response response = memberMapper.memberToResponse(savedMember);

        return new ResponseEntity(response, HttpStatus.OK);

    }
}

 

 

이렇게 MemberMapper 빼고 Member 도메인의 클래스들을 적어봤는데

기존의 프로젝트 파일에 적용하다보니 굳이 싶은 코드들이 좀 있어서 참고만 했으면 좋겠다

 

'SPRING-SECURITY' 카테고리의 다른 글