이제 프로젝트를 시작하는데 로그인 기능을 어떻게 구현해야 할지 몰라서 강의를 보면서 공부하였다.
먼저 response와 request의 dto를 작성해 주었다.
sign-in.request.dto.ts
export default interface SignInRequestDto {
email: string;
password: string;
}
sign-in.response.dto.ts
import ResponseDto from "../response.dto";
export default interface SignInResponseDto extends ResponseDto {
token: string;
expirationTime: number;
}
response.dto.ts
import { ResponseCode } from "types/enum";
export default interface ResponseDto {
code: ResponseCode;
message: string;
}
이렇게 작성해주고 apis 폴더의 index.ts에 아래와 같은 내용을 작성해주었다.
import axios from "axios";
import { SignInRequestDto, SignUpRequestDto } from "./request/auth";
import { SignInResponseDto } from "./response/auth";
import { ResponseDto } from "./response";
const DOMAIN = "http://localhost:4000";
const API_DOMAIN = `${DOMAIN}/api/v1`;
const SIGN_IN_URL = () => `${API_DOMAIN}/auth/sign-in`;
const SIGN_UP_URL = () => `${API_DOMAIN}/auth/sign-up`;
export const signInRequest = async (requestBody: SignInRequestDto) => {
const result = await axios
.post(SIGN_IN_URL(), requestBody)
.then((response) => {
const responseBody: SignInResponseDto = response.data;
return responseBody;
})
.catch((error) => {
if (!error.response) return null;
const responseBody: ResponseDto = error.response.data;
return responseBody;
});
return result;
};
export const signUpRequest = (requestBody: SignUpRequestDto) => {};
axios 라이브러리를 사용하여 HTTP 요청을 보내고, 그 결과를 처리하는 (async/await)으로 비동기 함수들을 정의하고 있다. SIGN_IN_URL주소에 requestBody와 같이 post 요청을 보낸다. 요청이 성공적으로 되면 response를 받아서 response.data를 반환한다. 만약 아니라면 error를 반환한다.
그리고 로그인 페이지로 가서 로그인 함수를 만들어 준다.
로그인 후 서버로부터 받은 토큰을 쿠키에 저장하고, 특정 페이지로 사용자를 리다이렉트한다. react-cookie라이브러리를 사용했다.
//function: sign in response 처리 함수
const signInResponse = (
responseBody: SignInResponseDto | ResponseDto | null
) => {
if (!responseBody) {
alert("네트워크 이상입니다.");
return;
}
const { code } = responseBody;
if (code === "DBE") {
alert("데이터베이스 오류입니다.");
}
if (code === "SF" || code === "VF") {
setError(true);
}
if (code !== "SU") return;
const { token, expirationTime } = responseBody as SignInResponseDto;
const now = new Date().getTime();
const expires = new Date(now + expirationTime * 3600);
setCookies("accessToken", token, { expires, path: MAIN_PATH() });
navigator(MAIN_PATH());
};
//event handler : 로그인 버튼 클릭 이벤트 처리
const onSignInButtonClickHandler = () => {
const requestBody: SignInRequestDto = { email, password };
signInRequest(requestBody).then(signInResponse);
};
signInRequest를 실행해서 성공적으로 되면 signInResponse 함수를 실행시킨다.
token : 서버에서 발급한 엑세슨 토큰으로, 사용자가 인증된 상태임을 나타낸다.expirationTime : 토큰의 만료 시간으로, 일반적으로 몇 시간 후 토큰이 만료될지를 나타낸다.new Date().getTime()은 현재 시간을 유닉스 타임스탬프(1970년 1월 1일 00:00:00 UTC 이후의 경과 시간)로 반환합니다.const expires = new Date(now + expirationTime * 3600)setCook("accessToken", token, {expires, path:MAIN_PATH()})setCookies 함수는 쿠키에 데이터를 저장하는 함수"accessToken": 쿠키의 이름으로, 저장할 데이터의 키token: 쿠키에 저장할 데이터로, 서버에서 발급한 엑세스 토큰{expires, path: MAIN_PATH()}: 쿠키 옵션을 지정expires : 쿠키의 만료 시간을 지정path : 쿠키가 유요한 경로를 지정.MAIN_PATH()함수가 반환하는 경로에만 쿠키가 적용cookie 유요한 경로 부가 설명
쿠키의
path옵션은 쿠키가 유효한 URL 경로를 지정합니다. path 옵션의 설정에 따라 쿠키가 어느 경로에서 유효한지가 결정됩니다.
path가 /로 설정된 경우:
쿠키는 해당 도메인의모든 경로에서유효합니다. 예를 들어, path: "/"로 설정하면, /, /board, /profile 등 모든 경로에서 쿠키에 접근할 수 있습니다.