프론트엔드를 개발하다보면 백엔드 api가 없어 개발에 난감한 경우가 있다.
그렇다고 openAPI만 사용하기엔 커스텀할 수 있는 내용이 적어 원하는 기능을 테스트 해보기가 어려운 순간도 있다. 그래서 가짜 api통신이 가능하도록 moke api를 만들려고 한다. 가짜 api를 만드는 방법은 여러가지가 있지만, 그중에서 json-server가 가장 간단하게 구현할 수 있다는 생각이 들어 채택했다.
npm i json-server-auth json-server
설치 후 파일 의존성이 잘 되어있는지 확인할 필요가 있다. 나는 처음에 에러가 떠서 뭔가 했는데 알고보니 의존성 오류였다..
우선 api의 json을 저장할 db.json 파일을 루트폴더에 만든다.
파일엔 유저를 저장할 users를 만든다.
{
"users": []
}
앞으로 회원가입시 user에 유저들이 들어올 것이다.
pakege.json 파일의 skript에 명령어를 만든다.
"scripts": {
"server": "json-server-auth --watch db.json --port 4444"
}
watch 뒤에는 db가 저장된 json파일을 적고, port 뒤에는 서버를 열 포트 번호를 붙여준다. port를 붙이지 않으면 기본적으로 3000으로 열리는데, 리액트와 번호가 같으니 변경해주자.
json-server-auth의 경우 JWT로 인증이 가능하다.
셋중 어떤 routes를 써도 상관 없다.
POST /register
POST /signup
POST /users
register에는 아래와 같은 정보를 요구한다.
POST /register
{
"email": "olivier@mail.com",
"password": "bestPassw0rd"
}
회원가입시 자동으로 db.json에 값이 저장된다.
"users": [
{
"email": "test@test.com",
"password": "$2a$10$YEM/FjW29ESgJenmfIE9t.HWQ0zQB5k.X1y9dtMifedhy4sXSI/0m",
"id": 1
}
]
POST /login
POST /signin
login 또한 이메일과 비밀번호를 필요로한다.
POST /login
{
"email": "olivier@mail.com",
"password": "bestPassw0rd"
}
JWT토큰을 전달받는다.
{
"accessToken": "xxxx-xxxxx-xxxx",
"user": {
"email": "test@test.com",
"id": 1
}
}
import axios from "axios";
import React, { useEffect, useState } from "react";
function App() {
const [token, setToken] = useState("");
const [userId, setUserId] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [signupEmail, setSignupEmail] = useState("");
const [signupPassword, setSignupPassword] = useState("");
const login = async () => {
try {
const { data } = await axios.post("http://localhost:4444/login", {
email,
password
});
console.log(data)
setToken(data.accessToken);
setUserId(data.user.id);
console.log(data.accessToken);
alert("로그인 성공");
} catch (error) {
console.error("로그인 실패:", error.response?.data || error.message);
}
};
const signup = async () => {
try {
await axios.post("http://localhost:4444/signup", {
email: signupEmail,
password: signupPassword
});
alert("회원가입이 완료되었습니다.");
setSignupEmail("");
setSignupPassword("");
} catch (error) {
console.error("회원가입 실패:", error.response?.data || error.message);
}
};
return (
<>
{/* Signup Form */}
<div>
<h2>회원가입</h2>
<input
placeholder="이메일"
type="email"
value={signupEmail}
onChange={(e) => setSignupEmail(e.target.value)}
/>
<input
placeholder="비밀번호"
type="password"
value={signupPassword}
onChange={(e) => setSignupPassword(e.target.value)}
/>
<button onClick={signup}>회원가입</button>
<br />
</div>
{/* Login Form */}
<div>
<h2>로그인</h2>
<input
placeholder="이메일"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
placeholder="비밀번호"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button onClick={login}>로그인</button>
<br />
</div>
</>
);
}
export default App;