원래는 다음주 수요일에 할 발표준비를 했어야하는데..
DB 배운 김에 DB연결을 마무리하려고한다. 코어타임 출발까지 남은 시간 90분
그 전에 재학생 / 비재학생 여부를 구분하기 위해서 role 변수를 사용했는데 솔직히 그럴 필요 없이 토큰이 있으면 회원(재학생) / 없으면 비회원(비재학생)으로 구분하면 되는터라 그 변수를 모두 없앴다.
우선은 DB에 저장할 유저정보부터 좀 수정해야한다.
package com.hongchelin.Domain;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Builder;
import lombok.Data;
@Entity
@Data
@Builder
public class Member {
@Id
@GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY)
private Long id;
private String name;
private String role;
private String refreshToken;
}
기존에는 이름, 권한, 리프레시토큰 정도를 저장했는데, 이제는 좀 여러 개가 필요하다.
우선 이 Member 객체를 어디서 쓸거나면..
- 로그인 시 DB에 저장
- 회원가입 시 DB에 저장
이정도?

이정도를 받아야한다.
이러면 requestDTO도 만들어서 받아야한다.
TDD를 써보자니 시간이 좀 걸리고 (TDD는 DDD할 때 해보기로)
대략적인 개발 플로우만 써보자면
이름, 아이디, 비밀번호를 컨트롤러가 받아 서비스로 넘기고, 서비스는 이를 받아서 DB에 저장한다.
package com.hongchelin.Service.signup;
import com.hongchelin.Domain.Member;
import com.hongchelin.Repository.MemberRepository;
import com.hongchelin.dto.Request.MemberRequestDTO;
import com.hongchelin.dto.user.ResponseDTO;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
@Service
public class SignUpService {
private final MemberRepository memberRepository;
public SignUpService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public ResponseEntity<ResponseDTO> signUp(MemberRequestDTO memberRequestDTO) throws Exception {
try {
String nickname = memberRequestDTO.getNickname();
String userId = memberRequestDTO.getUserId();
String password = memberRequestDTO.getPassword();
Member member = Member.builder()
.nickname(nickname)
.userId(userId)
.password(password)
.build();
memberRepository.save(member);
ResponseDTO responseDTO = ResponseDTO.builder()
.status(200)
.message("성공")
.build();
return ResponseEntity.status(HttpStatus.OK).body(responseDTO);
} catch(Exception e) {
e.printStackTrace();
ResponseDTO responseDTO = ResponseDTO.builder()
.status(500)
.message("에러")
.build();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseDTO);
}
}
}
코드

웹브라우저에서는 POST 요청을 보내기 어려워서 POSTMAN으로 보냈다.

성공
리프레시 토큰은 발급되지 않아서 null이고, 나중에 로그인할 때 다시 발급하면 된다.
이제 뼈대는 만들었으니, 해야할 것은
id, 비번으로 로그인할 때 이걸 대조하기만 하면 된다.

원래 소셜로그인 버튼이 있었는데 어디갔지.
암튼 저거에 대응하는 코드들을 만들었다.
package com.hongchelin.Service.login;
import com.hongchelin.Domain.Member;
import com.hongchelin.Repository.MemberRepository;
import com.hongchelin.Service.JWT.JWTFilter;
import com.hongchelin.dto.Request.MemberRequestDTO;
import com.hongchelin.dto.user.ResponseDTO;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class LoginMainService {
private final JdbcTemplate jdbcTemplate;
private final MemberRepository memberRepository;
private final JWTFilter jwtFilter;
public LoginMainService(JdbcTemplate jdbcTemplate, MemberRepository memberRepository, JWTFilter jwtFilter) {
this.jdbcTemplate = jdbcTemplate;
this.memberRepository = memberRepository;
this.jwtFilter = jwtFilter;
}
public ResponseEntity<ResponseDTO> login(String secret, MemberRequestDTO memberRequestDTO) {
String userId = memberRequestDTO.getUserId();
Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM member WHERE user_Id = ?", Integer.class, userId);
if (count == 1) { //정보 있음. 로그인
String ideintifier = jdbcTemplate.queryForObject("SELECT identifier FROM MEMBER WHERE user_Id = ?", String.class, userId);
ResponseDTO responseDTO = ResponseDTO.builder()
.status(200)
.message("성공")
.accessToken(jwtFilter.createToken(secret, ideintifier))
.refreshToken(jwtFilter.createRefreshToken(secret, ideintifier))
.build();
return ResponseEntity.status(HttpStatus.OK).body(responseDTO);
} else {
ResponseDTO responseDTO = ResponseDTO.builder()
.status(400)
.message("없는 아이디입니다.")
.build();
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseDTO);
}
}
}
코드

테스트1-회원정보 없음

테스트2 - /signup에서 회원가입 절차를 한 번 진행한 후에 테스트
모두 성공
기쁘다.

identifier가 없어서 다시 저장했다.
이러고 코어타임 감 지금부터는 코어타임에서 쓰는거
생각해보니 token이 필요할까 싶었다. 사실 최초로그인과 토큰 만료시에만 필요하기 때문에.. token 도메인/레포지토리로 분리하였다.
해야할 거
- 토큰 도메인 / 레포지토리 만들기
- 로그인 성공 시 정보 저장하기 -> 리프레시토큰이나 뭐 이런거
- 액세스 토큰 만료 시에 불러오기

이게 아마 MEMBER 테이블로 쓰이지 않을까 싶다.
받는 요소는 email, nickname(닉네임), password, user_id (로그인할 때 쓰는거)
코드 중간중간에 나올 identifier는 user_id로 사용하도록. 어차피 user_id는 못 바꾸게 할 예정이라 식별자로 써도 무방하다.
사실 오늘 개발 공부만 몇 시간한데다 머리도 아파서 JWTFilter처럼 DB 처리하는 것만 하나로 빼놨으면 좋겠는데 오늘은 무리 내일 합시다.
해야할거
예외처리
- DB에 MEMBER에서 같은 것이 있을 경우 회원가입 못하게
- Validator 사용하기
- 좀 맑은 정신에서 개발해보기
- API명세서 2.0 작성
'팀 프로젝트 > [2025][GDG]홍대 맛집 아카이빙 프로젝트' 카테고리의 다른 글
| [GDG] 홍대 맛집 아카이빙 프로젝트 #11 - 로그인/회원가입 마무리 (진) (2) | 2025.07.31 |
|---|---|
| [GDG] 개발코스 4주차 WIL (5) | 2025.07.29 |
| [GDG]홍대 맛집 아카이빙 프로젝트 #10 - H2 DB 연결하기 (3) | 2025.07.27 |
| [GDG]홍대 맛집 아카이빙 프로젝트 백엔드 개발 #9 - 회원가입 기능 개발하기 (1) | 2025.07.22 |
| [GDG]홍대 맛집 아카이빙 프로젝트 백엔드 개발 #8 - 투표기능 개발하기 (4) | 2025.07.21 |