What I Learnd/TIL
TIL - TypeScript로 회원가입, 로그인 기능 구현하기
키싸
2023. 8. 2. 01:18
타입스크립트로 회원가입과 로그인 기능을 구현하는 연습을 해보자.
프로젝트 셋업
- data.json 데이터 파일 셋업
- json-server 설치: yarn add json-server @types/json-server
- yarn create react-app <프로젝트 폴더 이름> --template typescript
- yarn start
- yarn json-server --watch db.json --port 4000
// 회원가입
import React from "react";
import { Form, Input, Button, Checkbox } from "antd";
import styled from "styled-components";
import axios from "axios";
const SignupForm: React.FC<any> = ({ setIsLogin }) => {
const handleSignup = async (values: any) => {
const { email, password, confirmPassword, agreed } = values;
try {
// TODO: 데이터베이스에서 email과 password 기반으로 찾아서 이미 존재하는지 확인 후, 존재하는 경우
const response = await axios.get(
`http://localhost:4000/users?email=${email}`
);
console.log("response", response.data);
if (response.data.length >= 1) {
alert("이미 존재하는 아이디입니다.");
return false;
}
// 회원가입 기능
await axios.post("http://localhost:4000/users", {
email: email,
password: password,
});
// TODO 성공
alert(
"회원가입이 성공적으로 처리되었습니다. 로그인 페이지로 이동합니다."
);
setIsLogin(true);
} catch (error) {
// TODO: 네트워크 등 기타 문제인 경우
return false;
}
};
return (
<FormWrapper onFinish={handleSignup}>
<Form.Item
label="이메일"
name="email"
rules={[{ required: true, message: "이메일을 입력해주세요." }]}
>
<Input />
</Form.Item>
<Form.Item
label="비밀번호"
name="password"
rules={[{ required: true, message: "비밀번호를 입력해주세요." }]}
>
<Input.Password />
</Form.Item>
<Form.Item
label="비밀번호 확인"
name="confirmPassword"
rules={[
{ required: true, message: "비밀번호 확인을 입력해주세요." },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue("password") === value) {
return Promise.resolve();
}
return Promise.reject(new Error("비밀번호가 일치하지 않습니다."));
},
}),
]}
>
<Input.Password />
</Form.Item>
<Form.Item
name="agreed"
valuePropName="checked"
rules={[
{
validator: (_, value) =>
value
? Promise.resolve()
: Promise.reject(
new Error("고객정보 이용동의에 체크해주세요.")
),
},
]}
>
<Checkbox>고객정보 이용동의</Checkbox>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
회원가입
</Button>
</Form.Item>
</FormWrapper>
);
};
export default SignupForm;
// 로그인
import React from "react";
import { Form, Input, Button } from "antd";
import styled from "styled-components";
import axios from "axios";
import shortid from "shortid";
const LoginForm: React.FC = () => {
const handleLogin = async (values: any) => {
const { email, password } = values;
// TODO: email과 password를 DB에서 찾아서 로그인 검증
try {
const response = await axios.get(
`http://localhost:4000/users?email=${values.email}&password=${values.password}`
);
// console.log("response", response.data);
if (response.data.length <= 0) {
// TODO: 일치하는 유저가 없는 경우
alert("일치하는 유저를 찾을 수 없습니다.");
return false;
} else {
alert("로그인에 성공하였습니다. 메인 페이지로 이동합니다.");
// TODO: localStorage에 token과 email을 저장
localStorage.setItem("token", shortid.generate());
localStorage.setItem("email", values.email);
// TODO: 성공 시(4), "/" 라우터로 이동
window.location.replace("/");
}
} catch (error) {
// TODO: 네트워크 등 기타 문제인 경우
alert("일시적인 오류가 발생하였습니다. 고객센터로 연락주세요.");
}
};
return (
<FormWrapper onFinish={handleLogin}>
<Form.Item
label="이메일"
name="email"
rules={[{ required: true, message: "이메일을 입력해주세요." }]}
>
<Input />
</Form.Item>
<Form.Item
label="비밀번호"
name="password"
rules={[{ required: true, message: "비밀번호를 입력해주세요." }]}
>
<Input.Password />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
로그인
</Button>
</Form.Item>
</FormWrapper>
);
};
export default LoginForm;