문제 발생
기능
- 사용자가 본인인증을 할때 인증 코드 메일 발송을 한다.
- 메일을 보내기 전에 인증 코드를 랜덤으로 생성하고 생성된 인증 코드를 HttpSession에 저장한다.
- 사용자는 메일에 적혀진 인증코드를 작성하고 인증하기 버튼을 클릭한다.
- 사용자가 입력한 인증 코드와 session에 저장된 인증코드가 같은지 확인한다.
문제
- 코드를 저장한 session과 사용자가 인증코드를 확인받는 로직에서 session에서 인증코드를 꺼내는데, 이 두개의 session이 불일치한다.
String storedCode = session.getAttribute("code").toString(); --> 여기서 session에 code 가 없다고 NullPointerException 이 발생한다.
문제 확인
- 인증 코드를 저장하는 로직과 인증코드를 확인하는 로직에 로그를 찍어본 결과 session 아이디가 달랐다.
[인증 코드 저장 api session 정보] mail session : org.apache.catalina.session.StandardSessionFacade@4c29be9f [인증 번호 확인 api session 정보] valid session : org.apache.catalina.session.StandardSessionFacade@3f1f206c
원인 분석
첫번째 (실패)
- react에서 인증코드를 보내는 화면과 인증코드를 확인받는 화면이 달라서 생기는 문제점인줄 알았다. (무식하게 생각)
- 따라서 react에서 화면 이동 없이 해당 로직을 처리하는 것으로 수정했다. 하지만 되지 않았다,,,
두번째(성공)
- 검색한 결과 브라우저는 기본적으로 서로 다른 도메인의 리소스를 요청할 때 보안상의 이유로 요청에 대해 인증 정보를 포함시키지 않는다고 한다. (same-origin-policy)
해결 방법
REACT
- session을 유지해야하는 api 통신에 withCredentials: true 옵션 추가
/**
* @description 인증 코드 이메일 발송
*/
const sendCodeEmail = async (params: { email: string }) => {
const url = `/user/send`;
const { data } = await request.post(url, params, {
withCredentials: true,
});
return data;
};
/**
* @description 인증 코드 확인
*/
const validInputCode = async (code: string) => {
const url = `/user/code/valid?code=${code}`;
const { data } = await request.get(url, {
withCredentials: true,
});
return data;
};
SPRING BOOT
- cors origin 설정에서 allowCredentials(true)로 설정한다.
@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {
private final long MAX_AGE_SECS = 3600;
@Override
public void addCorsMappings(CorsRegistry registry) {
// 모든 경로에 대해
registry.addMapping("/**")
// Origin이 localhost:3000에 대해
.allowedOrigins("http://localhost:3000")
// GET, POST, PUT, PATCH, DELETE, OPTIONS 메서드를 허용한다.
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true) // 이부분 설정
.maxAge(MAX_AGE_SECS);
}
}
'FE > React' 카테고리의 다른 글
[React] Email js 사용하여 사용자에게 이메일 보내기(form 제출X) (0) | 2023.07.25 |
---|---|
[React] axios API 통신시 header에 JWT token 보내기 (0) | 2023.07.08 |
[React] craco 절대경로 설정 방법(TypeScript) (0) | 2023.01.08 |
[Recoil] recoil을 사용하여 전역 상태 관리 하기 (1) | 2023.01.08 |