- ํ์ฌ
Front-End์Back-end๋ ๋ค๋ฅธ ํ๊ฒฝ์์ ๊ฐ๋ฐํ๊ณ ์์ - Proxy ๋ฅผ ์ฌ์ฉํ์ง ์์
์๋ ์ฐ๋ ํ์๊ฐ์ Form ์ ์์ ํ๋ Internal Server Error 500 ๊ฐ ๋ฌ๋ค.
function App() {
// const { data, isLoading, refetch } = useQuery("userData", getData, {
// onSuccess: (data) => {
// console.log(data);
// },
// onError: (error) => {
// console.log(error);
// },
// }); // 2023.05.02 ํ์ฌ GET ์์ฒญ๋ถ๋ถ์ด ์์ผ๋ฏ๋ก ์ฃผ์์ฒ๋ฆฌ
const { mutate } = OnPostData();ํด๋น ์ฌ์ ๋ฅผ ์๊ณ ๋ณด๋ Back-End ์์ GET ์์ฒญ์ ๋ฐ๋ ๋ถ๋ถ์ ์์ง ๋ง๋ค์ง ์์ ์๊ธด ๋ฌธ์
๊ฐ๋จํ๊ฒ GET ์์ฒญ์ ์ฃผ์์ฒ๋ฆฌ ํ์ฌ ํด๊ฒฐ ํจ
๋ก๊ทธ์ธ ์์ฒญ์ ์ ๋๋ก ๋ฐ์์ค๋์ง ํ์ธํ๊ธฐ ์ํด Form ์ ์ฑ์ POST ์์ฒญ์ ํจ
ํด๋นํ๋ ๋ฐ์ดํฐ ๊ฐ์ด ์กด์ฌํ์ง ์์ ์ failMsg ๋ฅผ ํตํด "๋ก๊ทธ์ธ ์ ๋ณด๊ฐ ์ผ์นํ์ง ์์ต๋๋ค." ๋ผ๋ ๋ฉ์ธ์ง๋ฅผ ๋ฐ์
Database ์ ์ผ์นํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ณ ๋ค์ POST ์์ฒญ
์ผ์นํ๋ ๋ฐ์ดํฐ๊ฐ ์์ ๊ฒฝ์ฐ ํด๋น ์์ด๋ ๋น๋ฐ๋ฒํธ ๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ์ ๋ณด๋ ์ ์์ ์ผ๋ก ๋ณด์ด๋ ๊ฒ์ ํ์ธ
์ถํ ํ ํฐํ ์์
- ๊ธฐ์กด์
localhost๋ http ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋๋ฐ, http ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฟ ํค ์ฌ์ฉ์ ๋ฒ๊ฑฐ๋ก์์ด ์์ผ๋ฏ๋ก ๋ณ๊ฒฝ - https ๋ก ๋ณ๊ฒฝํ๊ธฐ ์ํด
window๋choco,mac์brew๋ฅผ ์ฌ์ฉํดmksert๋ฅผ ์ฌ์ฉ - ์ฐธ๊ณ ์๋ฃ 1 ์ฐธ๊ณ ์๋ฃ 2
"scripts": {
"start": "set HTTPS=true&&react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
} // ๋จ์ํ set HTTPS ๋ฅผ ์ด์ฉํด https ๋ฅผ ๋ง๋ค ์ ์๋ค.ํ์ง๋ง ์ธ์ฆ์๊ฐ ์์ด์ ์ํํ๋ค๋ ๊ฒฝ๊ณ ๋ฉ์ธ์ง๊ฐ ์ถ๋ ฅ
๊ฐ๋ฐํ๋๋ฐ์๋ ์ง์ฅ์ด ์์ง๋ง ํด๊ฒฐํด๋ณด๋๋ก ํ์
choco install mkcert // choco ๋ฅผ ์ฌ์ฉํด mkcert ๋ฅผ ์ค์น
mkcert -install // ์ธ์ฆ์ ๋ฐ๊ธ์ ์ํด ํด๋น ํ๋ก์ ํธ์ ์ต์์ ๋๋ ํ ๋ฆฌ๋ก ์ด๋ ํ ์ค์น
ํด๋นํ๋ key ์ cert ํ์ผ์ ์์ฑํด ์ฃผ์ด์ผ ํ๋ฏ๋ก
mkcert -key-file ./key.pem -cert-file ./cert.pem "localhost"
๊ทธ ์ดํ SSL_CRT_FILE ๊ณผ SSL_KEY_FILE ์ ๊ฐ๊ฐ cert.pem, key.pem ์ผ๋ก ๋งค์น ์์ผ์ค
"scripts": {
"start": "set HTTPS=true&&set SSL_CRT_FILE=cert.pem&&set SSL_KEY_FILE=key.pem&&react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},npm start
๊ฒฝ๊ณ ์ฐฝ์ด ์ฌ๋ผ์ง๊ณ localhost ๊ฐ https ๋ก ์ ์ ์ถ๋ ฅ ๋๋ ๊ฒ์ ๋ณผ ์ ์์
Back-end ์์ header ์ Authorization ์ ๋ด์ ์ฃผ๊ธฐ ์ํด ํ
์คํธ.
ํ
์คํธ url ์ POST ์์ฒญ์ ๋ณด๋์ผ๋ฉฐ request:200 ์ด ์ ์์ ์ผ๋ก ๋จ๋ ๊ฒ์ ํ์ธ
์๋ต์ผ๋ก ๋ฐ์ result ์ Bearer + TOKEN ๊ฐ์ด ์ ๋๋ก ๋ด๊ฒจ ์จ ๊ฒ์ ํ์ธ ํ ์ ์์
์ด์ ํด๋น ํ
์คํธ url ์ด ์๋ ๊ธฐ์กด์ ์ฌ์ฉํ๋ api/user/login url ์ ์ฐ๊ฒฐ
๋ณธ url ์ธ api/user/login url ์ request-header ์ authorization ์ด ์ ๋๋ก ๋ด๊ธด ๊ฒ์ ํ์ธ ํ ์ ์์
์ด์ ํด๋นํ๋ TOKEN ๊ฐ์ localStorage ์ ๋ด์ ์ฌ์ฉ ํ ๊ฒ
localStorage๋ ๋ธ๋ผ์ฐ์ ๋ด token ์ ์ ์ฅํด ๋ค์ ์ผ๋ ํด๋น ๊ฐ์ ์ฌ์ฉํ๊ธฐ ์ํจ (login, logout)- ์๋ต์ header (response.header) ๋
JSONํ์์ด๋ฏ๋ก ๊ทธ๋ฅ ์ ๊ทผํ๋ฉด null or undefined ์ค๋ฅ๊ฐ ๋๋ฏ๋กJSON.stringify๋ก ์์ ํด ์ ๊ทผํด์ผ ํจ
// api.ts
export const postData = async (data: IFormData) => {
return await axios.post(API_URL, data).then((response) => {
if (response.status === 200) {
axios
.post(API_URL, data)
.then((response) => {
console.log(response);
let ACCESS_TOKEN = JSON.stringify(response.headers["authorization"]);
// JSON ํ์์ด๋ฏ๋ก JSON.stringify ๋ฅผ ์ฌ์ฉํด ์ฃผ์ด์ผ ํ๋ค. (*๋์๋ฌธ์ ์ฃผ์*)
// ACCESS_TOKEN ์ผ๋ก ์ด๊ธฐํ
console.log(ACCESS_TOKEN);
localStorage.setItem("loginToken", ACCESS_TOKEN);
console.log(localStorage.getItem("loginToken"));
// localStorage ์ ์ ๋๋ก ๊ฐ์ด ๋ด๊ฒผ๋์ง ํ์ธํ๊ธฐ ์ํด ์ฌ์ฉ
})
.catch((error) => {
console.log(error);
});
}
});
};F12 > application > local storage ๋ฅผ ํ์ธํด๋ณด๋ฉด ํด๋น localStorage ์ ์ ์์ ์ผ๋ก Token ๊ฐ์ด ์ ์ฌ ๋ ๊ฒ์ ๋ณผ ์ ์์
//api.ts
// Header ์ ๊ฐ ๋ฃ์ด์ฃผ๋ ๋ฐฉ๋ฒ 1.
export async function getData() {
const request: HeadersInit = new Headers();
// Headers ๋ก ์ง์ ํค๋๋ฅผ ์์ฑ
let token = await JSON.parse(localStorage.getItem("loginToken") || "{}");
// ์ Header ์ ๋ฐ์์ JSON ํ์์ผ๋ก ๋ฐ๊ฟ ์ฌ์ฉ
// JSON.parse ๋ ts ๋ด์์ || ๋ก ๋น {} ๊ฐ์ ๋ณด๋ด์ฃผ์ด์ผ type error๊ฐ ๋์ง์์
if (!token) {
throw new Error("error");
} else {
request.set("authorization", token);
// header ์ authorization ์ผ๋ก ๊ฐ์ ์ธํ
ํ
}
return await fetch(BOARD_URL, {
method: "GET",
headers: request, // ๋ฃ์ด์ค
}).then((response) => {
...
// Header ์ ๊ฐ ๋ฃ์ด์ฃผ๋ ๋ฐฉ๋ฒ 2
export const axiosPostData = async (data: IBoardData) => {
return await axios.post(BOARD_URL, data, {
headers: {
Authorization: await JSON.parse(
localStorage.getItem("loginToken") || "{}"
),
},
});
};- ๊ฒ์๊ธ ์์์ ๋ณด์ธ
board๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํดaxios๋ฅผ ์ฌ์ฉ header > Authorization์localStorage๋ฅผ ์ ์ฌํด ์์ฒญํ๋ ๊ฒ์ด ๊ด๊ฑด- header ์ ํ ํฐ์ด ์กด์ฌํ์ง ์์ ์ ์์ฒญ์ ๊ฑฐ๋ถํจ
export async function axiosGetData() {
const request: HeadersInit = new Headers();
let token = await JSON.parse(localStorage.getItem("loginToken") || "{}");
// ์ Header ์ ๋ฐ์์ JSON ํ์์ผ๋ก ๋ฐ๊ฟ ์ฌ์ฉ
// JSON.parse ๋ ts ๋ด์์ || ๋ก ๋น {} ๊ฐ์ ๋ณด๋ด์ฃผ์ด์ผ type error๊ฐ ๋์ง์์
if (!token) {
throw new Error("error");
} else {
request.set("authorization", token);
}
return axios.get(BOARD_URL, {
headers: {
Authorization: token,
},
});
}- ๊ฒ์๊ธ์ ์์ฑํ๊ธฐ ์ํด ์์
form์ ์์ฑ - ์๋ ์ฌ์ฉํ๋ ๋ก๊ทธ์ธ์
useQuery์ ๊ฒน์น๋ฏ๋กrenameํ์ localStorage์ ๋ด๊ธด ํ ํฐ์ด ๋ค๋ฅด๋ฉด ๊ธ ์์ฑ ์ Back-End ์์ ๊ตญ์ ์ด ๋ฐ๋๊ฒ ์ค์
//api.ts
export const OnAxiosPostData = () => {
return useMutation(axiosPostData);
};
export const axiosPostData = async (data: IBoardData) => {
return await axios.post(BOARD_URL, data, {
headers: {
Authorization: await JSON.parse(
localStorage.getItem("loginToken") || "{}"
),
},
});
};
//App.tsx
const {
register: boardReg,
handleSubmit: boardHandle,
setError: boardSetError,
formState: { errors: boardErrors },
} = useForm<IBoardData>();
...
return (
)๋ค๋ฅธ ํ ํฐ์ผ๋ก ๋ก๊ทธ์ธ ํ ๊ธ์ ์์ฑ ์ ์ ์์ ์ผ๋ก ๊ตญ์ ์ด ๋ฐ๋๋ ๋ชจ์ต













