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;