본문 바로가기
프로젝트/로그인, 회원가입

4. 아이디 찾기

by 갱생angel 2024. 5. 24.

※이메일을 통해 사용자의 ID 찾기

  -ID 찾기 페이지 추가

  -로그인 페이지에 ID 찾기 페이지로 이동 버튼 추가

  -Login.js, Register.js css 수정

 

-백엔드-

 

controller - <userController.js>

(...)

//Post Find User_id, /find_id : ID 찾기
const findId = asynchHandler(async (req, res) => {
  const { email } = req.body; //클라이언트에서 보낸 이메일 값을 받아옴
  const user = await User.findOne({ email }); //클라이언트에서 보낸 이메일 값 document 확인
  if (!user) { //document가 없을 경우
    return res.status(401).json({ message: "존재하지 않는 이메일입니다." });
  } else { //document가 없을 경우
    res.status(201).send(user); //document 정보를 클라이언트로 보냄
  }
});

(...)

 

route - <userRoute.js>

const express = require("express");
const router = express.Router();
const {
  getUserData,
  loginUser,
  findId,
  registerUser,
  addImageScore,
  addCombineScore,
} = require("../controller/userController");
const { authUser } = require("../middleware/authMiddleware");

router.route("/login").get(authUser, getUserData).post(loginUser);
router.route("/find_id").post(findId); //ID 찾기 라우터 추가
router.route("/register").post(registerUser);
router.route("/imageScore").post(authUser, addImageScore);
router.route("/combineScore").post(authUser, addCombineScore);

module.exports = router;

-프론트엔드-

 

page - <IdFind.js> : ID 찾기 페이지

import React, { useEffect, useState } from "react";
import "../../css/user.css";
import axios from "axios";
import { useNavigate } from "react-router-dom";

function IdFind() {
  const navigate = useNavigate();

  const [isFind, setIsFind] = useState(false); //ID 찾음 여부

  const [email, setEmail] = useState(""); //이메일 state
  const [username, setUsername] = useState(""); //ID state

  const [emailError, setEmailError] = useState(""); //이메일 에러 state

  const changeEmail = (e) => setEmail(e.target.value);

  const IdFindSubmit = async (e) => { //ID 찾기 함수
    e.preventDefault();

    const idData = { email: email }; //서버에 보낼 데이터

    if (email === "") {
      alert("빈칸을 입력해주세요.");
    } else {
      try {
        await axios
          .post("http://localhost:5000/find_id", idData)
          .then((res) => {
            setUsername(res.data.username); //사용자 ID 저장
            setIsFind(true);
          });
      } catch (err) {
        setEmailError(err.response.data.message); //에러 메시지 표시
      }
    }
  };

  useEffect(() => { //localStorage에 토큰이 있을 경우
    if (localStorage.getItem("token") !== null) navigate("/main"); //메인 페이지로 이동
  }, [navigate]);

  return (
    <div className="userContainer">
      <h1>ID 찾기</h1>
      {isFind ? (
        <div>
          <h2>ID : {username}</h2>
          <button className="submitBtn" onClick={() => navigate("/")}>
            로그인
          </button>
        </div>
      ) : (
        <div>
          <form onSubmit={IdFindSubmit}>
            <div>
              <label>이메일</label>
              <input
                type="text"
                value={email}
                onChange={changeEmail}
                placeholder="ex) admin@aaa.com"
              />
              <h4>{emailError}</h4>
            </div>
            <button className="submitBtn">ID 찾기</button>
          </form>
          <p onClick={() => navigate("/")}>-#로그인-</p>
        </div>
      )}
    </div>
  );
}

export default IdFind;

 

page - <Login.js> : 로그인 페이지

import React, { useEffect, useState } from "react";
import axios from "axios";
import "../../css/user.css";
import { useNavigate } from "react-router-dom";

function Login() {
  const navigate = useNavigate();

  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const [usernameError, setUsernameError] = useState("");
  const [passwordError, setPasswordError] = useState("");

  const changeUsername = (e) => setUsername(e.target.value);
  const changePassword = (e) => setPassword(e.target.value);

  const loginSubmit = async (e) => {
    e.preventDefault();

    const loginData = { username: username, password: password };

    if (username === "" || password === "") {
      alert("빈칸을 입력해주세요.");
    } else {
      try {
        await axios
          .post("http://localhost:5000/login", loginData)
          .then((res) => {
            alert(res.data.message);
            const { token } = res.data;
            localStorage.setItem("token", token);
            navigate("/main");
          });
      } catch (err) {
        setUsernameError(err.response.data.nameMessage);
        setPasswordError(err.response.data.pwdMessage);
      }
    }
  };

  useEffect(() => {
    if (localStorage.getItem("token") !== null) navigate("/main");
  }, [navigate]);

  return (
    <div className="userContainer">
      <h1>로그인</h1>
      <p></p>
      <form onSubmit={loginSubmit}>
        <div>
          <label>ID</label>
          <input type="text" value={username} onChange={changeUsername} />
          <h4>{usernameError}</h4>
        </div>
        <div>
          <label>비밀번호</label>
          <input type="password" value={password} onChange={changePassword} />
          <h4>{passwordError}</h4>
        </div>
        <button className="submitBtn" type="submit">
          로그인
        </button>
      </form>
      <div className="findDiv">
        <button className="findBtn" onClick={() => navigate("/find_id")}>
          ID 찾기
        </button>
        <button className="findBtn2">비밀번호 찾기</button>
      </div>
      <p onClick={() => navigate("/register")}>-#계정 생성-</p>
    </div>
  );
}

export default Login;

 

page - <Register.js> : 회원가입 페이지

import React, { useEffect, useState } from "react";
import axios from "axios";
import "../../css/user.css";
import { useNavigate } from "react-router-dom";

function Register() {
  const navigate = useNavigate();

  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [password2, setPassword2] = useState("");
  const [email, setEmail] = useState("");

  const [usernameError, setUsernameError] = useState("");
  const [passwordError, setPasswordError] = useState("");
  const [emailError, setEmailError] = useState("");

  const changeUsername = (e) => setUsername(e.target.value);
  const changePassword = (e) => setPassword(e.target.value);
  const changePassword2 = (e) => setPassword2(e.target.value);
  const changeEmail = (e) => setEmail(e.target.value);

  const registerSubmit = async (e) => {
    e.preventDefault();

    const inputs = [username, password, password2, email];
    const registerData = {
      username: username,
      password: password,
      chackPassword: password2,
      email: email,
    };

    if (inputs.some((input) => input === "")) {
      alert("빈칸을 입력해주세요.");
    } else {
      try {
        await axios
          .post("http://localhost:5000/register", registerData)
          .then((res) => {
            alert(res.data.message);
            navigate("/");
          });
      } catch (err) {
        setUsernameError(err.response.data.nameMessage);
        setPasswordError(err.response.data.pwdMessage);
        setEmailError(err.response.data.emailMessage);
      }
    }
  };

  useEffect(() => {
    if (localStorage.getItem("token") !== null) navigate("/main");
  }, [navigate]);

  return (
    <div className="userContainer">
      <h1>회원가입</h1>
      <form onSubmit={registerSubmit}>
        <div>
          <label>ID</label>
          <input type="text" value={username} onChange={changeUsername} />
          <h4>{usernameError}</h4>
        </div>
        <div>
          <label>비밀번호</label>
          <input type="password" value={password} onChange={changePassword} />
          <h4>{null}</h4>
        </div>
        <div>
          <label>비밀번호 확인</label>
          <input type="password" value={password2} onChange={changePassword2} />
          <h4>{passwordError}</h4>
        </div>
        <div>
          <label>이메일</label>
          <input
            type="text"
            value={email}
            onChange={changeEmail}
            placeholder="ex) admin@aaa.com"
          />
          <h4>{emailError}</h4>
        </div>
        <button className="submitBtn" type="submit">
          회원가입
        </button>
      </form>
      <p onClick={() => navigate("/")}>-#로그인-</p>
    </div>
  );
}

export default Register;

 

css - <user.css>

.userContainer h1, h2 {
  text-align: center;
  margin-bottom: 60px;
}
.userContainer h2 {
  color: blue;
}
.submitBtn {
  width: 105%;
  padding: 10px;
  font-size: 20px;
  font-weight: bold;
  border: none;
  margin-top: 20px;
}
.submitBtn:hover {
  background-color: black;
  color: white;
}
.findDiv {
  display: flex;
  justify-content: space-between;
  width: 105%;
}
.findBtn, .findBtn2 {
  width: 70%;
  padding: 10px;
  font-size: 20px;
  font-weight: bold;
  border: none;
  margin-top: 20px;
}
.findBtn2 {
  margin-left: 30px;
}
.findBtn:hover, .findBtn2:hover {
  background-color: black;
  color: white;
}

 

<App.js>

import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Login from "./page/User/Login";
import Register from "./page/User/Register";
import PostAdd from "./page/Comunity/PostAdd";
import PostList from "./page/Comunity/PostList";
import PostDetail from "./page/Comunity/PostDetail";
import PostUpdate from "./page/Comunity/PostUpdate";
import Home from "./page/Home";
import ImageRegist from "./page/Game/ImageRegist";
import ImageGame from "./page/Game/ImageGame";
import CombineGame from "./page/Game/CombineGame";
import IdFind from "./page/User/IdFind";

function App() {
  return (
    <div>
      <BrowserRouter>
        <Routes>
          <Route index element={<Login />} />
          <Route path="/find_id" element={<IdFind />} /> <!--ID 찾기 페이지 라우터-->
          <Route path="/register" element={<Register />} />
          <Route path="/main" element={<Home />} />
          <Route path="/post" element={<PostList />} />
          <Route path="/post/add" element={<PostAdd />} />
          <Route path="/post/:id" element={<PostDetail />} />
          <Route path="/post/:id/update" element={<PostUpdate />} />
          <Route path="/image/add" element={<ImageRegist />} />
          <Route path="/imageGame" element={<ImageGame />} />
          <Route path="/combineGame" element={<CombineGame />} />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;

'프로젝트 > 로그인, 회원가입' 카테고리의 다른 글

6. 비밀번호 변경  (0) 2024.05.27
5. nodemailer, 인증코드  (0) 2024.05.27
3. 이메일, 정규 표현식  (0) 2024.05.23
2. JWT 토큰 검증  (0) 2024.05.20
1. user 파일, score 파일 병합  (0) 2024.05.20