대외활동/SSUPOWER : 학교 내부 길찾기 및 공강 스터디룸 예약 매칭 서비스

[SpringBoot] Login, Join with MariaDB

oxdjww 2023. 5. 16. 11:40
728x90
반응형

기술스택

> Front

    > React

> Back

    > SpringBoot

    > MariaDB

> Server

    > Cloudtype

 

학부 과정 중 소프트웨어프로젝트 과목에서 개발한 '학교 내부 길찾기 및 공강 스터디룸 예약 매칭 서비스' 이다.

 

본 글에서는 필자가 구현한 SpringBoot기반 Join, Login 및 배포과정을 다루었다.

 

1. start.spring.io

1. SpringBoot starter를 통해 파일을 만들어준다.

 

2. .zip 파일이 생성되면 압축해제 후 본인이 편한 디렉토리에 놓아준다.

... 저는 뭐가 많네요.. 본인이 생성하신 zip파일 압축해제하시면 됩니다

 

2. Join & Login API

본 프로젝트는 홈 화면이 로그인화면 이므로 MemberController를 통해 이를 구현해주었다.

그 외 회원가입이 되어있지 않아 회원가입 페이지로 이동하면 read()에서 처리해준다

@RequiredArgsConstructor
@RestController
public class MemberController {

    private final MemberService memberService;

    @PostMapping("/")
    public Long login(@RequestBody MemberLoginVO memberLoginVO) {
        String email = memberLoginVO.getEmail();
        String password = memberLoginVO.getPassword();

        Member member = memberService.findByEmail(email);
        if (member != null && member.getPassword().equals(password)) {
            // 로그인 성공
            return member.getId();
        } else {
            // 로그인 실패
            return null;
        }
}
    @PostMapping("/join")
    public Long create(@RequestBody Member member) {
        return memberService.save(member);
    }

    @GetMapping("/member/{id}")
    public Member read(@PathVariable Long id) {

        return memberService.findById(id);
    }

    @PostMapping("/member/{id}/update")
    public Long update(@PathVariable Long id, @RequestBody Member member) {
        return memberService.update(id, member);
    }

    @PostMapping("/member/{id}/delete")
    public Long delete(@PathVariable Long id) {
        memberService.delete(id);
        return id;
    }
}

회원정보를 저장하는 Member Entity

> Primary key는 id, 그 외 update, setPW 메서드도 구현하였다.

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String email;
    @Column(nullable = false)
    private String name;
    @Column(nullable = false)
    private String password;

    @Builder
    public Member(String email, String name, String password) {
        this.email=email;
        this.name=name;
        this.password=password;
    }

    public void update(String email, String name, String password) {
        this.email=email;
        this.name=name;
        this.password=password;
    }

    public void setPassword(String password) {
        this.password=password;
    }
}

로그인 폼을 담당하는 MemberLoginVO

@Getter
@Setter
public class MemberLoginVO {
    public MemberLoginVO() {

    }

    public MemberLoginVO(String email, String password) {
        this.email = email;
        this.password = password;
    }
    private String email;

    private String password;
}

SpringDataJPA담당하는 repository

> SpringDataJPA가 자동으로 지원해주지 않는 findByEmail은 따로 구현해주었다

public interface MemberJpaRepository extends JpaRepository<Member,Long> {
    Optional<Object> findByEmail(String email);
}

CRUD 지원하는 MemberService

@Service
@RequiredArgsConstructor
public class MemberService {
    private final MemberJpaRepository memberJpaRepository;

    @Transactional
    public Long save(Member member) {
        return memberJpaRepository.save(member).getId();
    }

    @Transactional
    public Long update(Long id, Member member) {
        Member currentMember = findById(id);
        currentMember.update(member.getEmail(), member.getName(), member.getPassword());
        return id;
    }

    @Transactional
    public void delete(Long id) {
        Member member = findById(id);
        memberJpaRepository.delete(member);
    }

	@Transactional
    public Member findById(Long id) {
        return memberJpaRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저입니다."));
    }

    @Transactional
    public Member findByEmail(String email) {
        return (Member) memberJpaRepository.findByEmail(email)
                .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저입니다."));
    }
}

3. Cloudtype 배포

https://app.cloudtype.io/

 

모두의 플랫폼팀, 클라우드타입

클라우드타입은 클라우드 기반 애플리케이션을 빠르게 개발하고 배포할 수 있는 클라우드 애플리케이션 플랫폼입니다.

cloudtype.io

회원가입 후 좌측 배너의 '+' 버튼으로 새 프로젝트를 생성해준다.

파란색 + 버튼을 클릭 후, 본인이 배포하고자 하는 템플릿인 SpringBoot를 선택해주었다.

배포하고자 하는 repo를 선택하면 되는데

이 때 사전작업이 필요하다

 

본인 github repository를 하나 생성해서 내부에 소스코드를 넣어준다

이렇게 디렉토리를 구성하면 되는데, 본인은 디렉토리 구조가 'red_test/privacy/소스코드' 여서 추가설정이 필요했다.

원래는 '레포지토리/소스코드' 이렇게 넣어주면 된다...

어떤 추가설정이 필요했는지는 바로 설명하겠다...

 

어쨌든 배포하고자하는 repository를 선택한 후, 다음과 같은 팝업이 뜬다.

 

java는 프로젝트에 알맞는 jdk version을 설정해주면 된다. 

이 때, mariaDB를 이용했기에 환경변수(Environment variables)를 설정해준다

mariadb이므로 port는 3306, 사용자하고자 하는 db username, pw를 입력해주면 된다.

그리고 배포하면 된다!

 

하지만..

본인은 레포지토리에 바로 소스코드가 있지 않고 privacy서브디렉토리 안에 있기에 서브 디렉토리 옵션을 추가해주었다.

배포가 안 돼서 구글링 후 서브 디렉토리 옵션을 걸어주었다.

그 후 재배포 했더니 성공적으로 배포된다!

 

MariaDB 서버는 다른 백엔드 팀원이 올려놔서 편하게 진행할 수 있었다.

이제 프론트 배포하고 연동하면 된다..😇

 

SSUPOWER 화이팅..!!

 

오류사항이나 지적은 댓글로 남겨주시면 감사하겠습니다!

 

+ 프론트 배포 후 연동 성공!

 

+ 중복 email로 회원가입 시 처리

@PostMapping("/join")
public Long create(@RequestBody Member member) {
    if(validateDuplicateMember(member)) {    //중복회원 검사
        return memberService.save(member);
    }else {
        return null;
    }
}

private boolean validateDuplicateMember(Member member) {
    if(memberJpaRepository.findByEmail(member.getEmail())
            .isPresent()){
        return false;
    }else return true;
}

+ react로 local test를 할 때

    @CrossOrigin(origins = "http://localhost:3000")

    이 필요하다고 한다..

+ Client(front)가 접근가능하도록 접근헤더도 추가해주어야 한다고 한다..

   .exposedHeaders("access-control-allow-origin")

 

728x90
반응형