1. SAI는 어떻게 동작하나요?
- SAI는 JWT를 기반으로 요청과 응답을 제공하는 RestAPI 서버입니다.
- JWT는 회원가입, 일반 로그인에서 제공됩니다.
a) Filter
- 회원가입과 일반 로그인을 요청할 때에는 JWT를 기반한 검증을 수행하지 않습니다.
- 그 외의 요청을 할 때에는 반드시 유효한 JWT를 쿠키로 보유하고 있어야 합니다.
- 이 부분은 Filter를 이용하여 구현했습니다.
- 아래의 코드는 JwtFilter 클래스의 한 부분입니다.
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response;
/* 해당 URL로 요청할 시에는 Cookie의 JWT 검증 안함 */
if (servletRequest.getRequestURI().equals("/api/join") ||
servletRequest.getRequestURI().equals("/api/email/validation") ||
servletRequest.getRequestURI().equals("/api/login")) {
chain.doFilter(request, response);
}
/* 그 외 URL로 요청할 시에는 Cookie의 JWT 검증 */
else if (jwtCookieService.validateAccessToken(servletRequest, servletResponse)) {
log.info("JwtFilter | Success: 토큰 검증 완료");
chain.doFilter(request, response);
}
/* Cookie의 JWT 검증 실패한 경우 */
else {
log.error("JwtFilter | Fail: 토큰 검증 실패");
servletResponse.setContentType(APPLICATION_JSON_VALUE);
servletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.writeValue(servletResponse.getOutputStream(), new ErrorResponse(ErrorCode.UNAUTHORIZED));
}
}
2. 기본 사용 방법
a) 회원가입
- SAI는 회원 가입에서 3가지 정보(이메일, 비밀번호, 회원 이름)를 요구합니다.
- 회원가입 또는 일반 로그인에 성공하면 다음과 같이 JWT를 쿠키에서 제공합니다.
b) 회원가입 - 중복 아이디(이메일)
- 프런트 쪽에서 이메일 중복 검사를 한다는 가정하에 작성된 코드이므로 중복 이메일을 이용하여
회원가입을 시도하면 아래의 사진과 같이 500 에러를 응답하도록 구현했습니다.
- 이와 같은 이유로 이메일 중복 검사 API를 따로 구현해두었습니다.
- 이 과정에서 중복 이메일이 DB에 입력되어 DataIntegrityValidationException이 발생하는데요,
이에 대한 처리를 아래의 사진처럼 구현했습니다.
- DB에 문제없이 데이터가 입력되는지 확인하기 위해 Flush()를 강제 호출하여
Service에서 결과를 반환하기 전에 오류가 발생한다면 이를 캐치하게 하도록 했습니다.
- 아래의 사진에서 확인할 수 있듯이, Excpetion Handler 클래스를 생성하여 내부의 Runtime Exception에서
해당 오류를 잡아내고 이에 따라 할당된 응답을 전달합니다.
3. 자동 로그인
a) 기본 메커니즘
- 자동 로그인의 경우 JWT 검증을 통해 진행됩니다.
- 기존에 회원가입 또는 일반 로그인 요청에 성공했다면 JWT를 쿠키로 보유하고 있을 테니까요
- 자동 로그인의 경우, Refresh 토큰의 유효성 검증을 통해 진행되며 검증을 통과한 경우
Access 토큰과 Refresh 토큰을 재발행(갱신)하는 방식으로 로직을 구현하였습니다.
- 아래의 코드는 자동 로그인 구현 처리 로직이며, MemberService 클래스의 일부분입니다.
// MemberApi - 자동 로그인
public void autoLoginApi(HttpServletRequest servletReq, HttpServletResponse servletResp) throws Exception {
servletResp.setContentType(APPLICATION_JSON_VALUE);
if (jwtCookieService.validateRefreshToken(servletReq)) {
String refreshToken = jwtCookieService.getRefreshToken(servletReq);
String email = jwtProvider.getUserEmail(refreshToken);
Member member = memberService.findByEmail(email);
String role = member.getRole();
jwtCookieService.setTokenInCookie(email, role, servletReq, servletResp);
log.info("Login Service | autoLoginApi() Success: refresh 토큰 로그인 성공 및 토큰 갱신");
objectMapper.writeValue(servletResp.getOutputStream(), new MemberResultResponse(Boolean.TRUE));
} else {
log.warn("Login Service | autoLoginApi() Fail: 토큰 검증 실패");
servletResp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
objectMapper.writeValue(servletResp.getOutputStream(), new ErrorResponse(ErrorCode.UNAUTHORIZED));
}
}
4. 대표 기능
a) 숙지해주세요!
- 회원가입, 자동 로그인, 일반 로그인을 제외한 나머지 API는 모두 Filter에서 제공하는 JWT 유효성 검증을
통과해야만 요청이 가능합니다.
- 본 포스팅의 가장 상단에 남겨놓은 Filter의 내부 메서드 코드에서 확인할 수 있듯이, 유효하지 않은
JWT를 사용한 요청은 다음과 같은 응답을 제공합니다.
b) 대표 기능 - 수치화(1)
- SAI는 사람 간의 교류를 바탕으로 인간관계를 수치화하기 위한 목적을 가지고 있습니다.
- 최초에 친구를 등록할 때 아래의 사진처럼 관계 상태(Relationship Status)를 결정하게 됩니다.
- 5가지 상태(great, positive, normal, negative, bad) 중 하나를 입력함에 따라 Enum이 선택되고,
선택된 Enum 값에 따라 정수 값이 등록됩니다.
c) 대표 기능 - 수치화(2)
- SAI는 이미 벌어진 일에 대한 기록을 리뷰하는 방식으로 인간관계를 수치화합니다.
- 그러므로 Event를 등록하고 이에 대한 평가를 기반으로 해당 Event에 참여한 친구 객체의 점수가 수정됩니다.
- 수정된 친구 객체의 점수에 따라 상태 값(Enum)이 업데이트됩니다.
c) 대표 기능 - 수치화(3)
- Event 등록과는 반대로 Event를 삭제하는 경우, 해당 Event의 평가에 따른 친구 객체의 점수 변화는
복구되어야 하겠죠? 그래서 다음과 같은 로직으로 구현했습니다.
d) 그 외 기능에 대하여
- 이 외 기능에 대한 사용 방법 또는 입력 데이터에 대한 설명은 API 문서에 예시가 작성되어 있으니,
이를 참고해주시면 감사하겠습니다.
https://restsai.herokuapp.com/swagger-ui/index.html
e) 업데이트(22년 11월 19일)
- Heroku 유료화로 인하여 해당 앱은 배포를 중지시킨 상태로, 더이상 동작하지 않습니다.
- 코드는 Github을 참고해주시면 감사하겠습니다.
'Side Projects > 프로젝트 사이' 카테고리의 다른 글
10. 배포 완료 (0) | 2022.09.14 |
---|---|
9. 개선사항(비즈니스 로직 제거, Exception Handler 적용, DataIntegrityViolationException 처리 방법) (0) | 2022.09.12 |
8. 백엔드 개발 완료(OpenAPI 소개 및 문제해결 회고록) (2) | 2022.09.06 |
7. 오류 해결 스토리 - constraint ["PUBLIC.UK_MBMCQELTY0"] (0) | 2022.07.30 |
6. 오류 해결 스토리 - Update/delete queries cannot be typed (0) | 2022.07.30 |
댓글