23/11/23 til firebase Authentication

2023. 11. 23. 23:51카테고리 없음

어제 보다 한층 나아진 firebase Authentication 하하하

 

아래는  Router.jsx  이다. raact router dom의  훅이나 기타등등을 설정하기위한 페이지

import { useState } from "react";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";   // 리액트라우터 돔에서
import Detail from "../pages/Detail";                                                              //필요한것들 임포트
import Home from "../pages/Home";
import MyPage from "../pages/MyPage";
import Register from "../pages/Register";
import Write from "../pages/Write";                      //라우트를 통해 이동할 페이지들 임포트

function Router() {
  const [users, setUsers] = useState({
    email: "없엉",                                       //회원가입 로그인 로그아웃 기능을 구현할 예정인데
    id: "이것도 없엉",                                 //그 회원이 로그인 할때 쓰여질 객체가 users다.
    isdone: false,                                        //초기값은 isdone외엔 쓰지 않는다.
    nickname: "마찬가지",                        //login이 되면 그 회원의 정보가  유저스에 재할당예정
  });
  console.log("유저스", users);
  return (
    <BrowserRouter>
      <Routes>                                            // 일단 유저스를 쓸 페이지들에 프롭스로 해당요소를 보내줌
        <Route path="/" element={<Home users={users} setUsers={setUsers} />} />
        <Route path="/detail" element={<Detail />} />
        <Route path="/mypage" element={<MyPage users={users} />} />
        <Route path="/write" element={<Write />} />
        <Route path="*" element={<Navigate replace to="/" />} />   // 요게 참 path를 별표시하면
        <Route                                                                                   //주소창 /뒤에 무슨값이 오던 
          path="/register"                                                          //이때 설정 된 element 주소로 간다고함
          element={<Register users={users} setUsers={setUsers} />}   //replace는 뒤로가기 버튼 눌렀을때
        />                                                                             //원래 페이지로 돌아와버리는 모순을 방지하기 위함
      </Routes>
    </BrowserRouter>
  );
}

export default Router;

 

아래는 Register.jsx    회원가입 로그인 로그아웃 함수가 주된기능이다.

import {
  createUserWithEmailAndPassword,
  getAuth,
  onAuthStateChanged,
  signInWithEmailAndPassword,
  signOut,
  updateProfile,
} from "firebase/auth";                                // 이거 터미널에서 파이어베이스 깔아줘야함            
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router";
import styled from "styled-components";

export default function Register({ setUsers, users }) {
  const [email, setEmail] = useState("");                    //밑에 인풋태그의 value들을 담을
  const [password, setPassword] = useState("");        //이메일 패스워드 닉네임
  const [nickname, setNickname] = useState("");     //닉네임은 회원가입시만 받는다.
  const auth = getAuth();
  const navigate = useNavigate();

  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      console.log("user", user);                     //유즈이펙트 어색해 복습필요
    });
  }, []);

  const onChange = (event) => {
    const {                                            //요게 어제 til에도 있던건데 
      target: { name, value },                // 이거 보통 onchange((e)=>{set어쩌고(e.target.value)})
    } = event;                                     //이렇게 많이 썻는데 요렇게도 쓰나봄
    if (name === "email") {
      setEmail(value);
    }

    if (name === "password") {
      setPassword(value);
    }
    if (name === "displayName") {     //어제랑 다른거는 displayName이라는것을 스스로추가한것
      setNickname(value);                    // 해당 태그의 네임이 요거이면 그떄의 벨류를 셋하겠다는로직
    } 
  };
  const signUp = async (event) => {
    event.preventDefault();
    try {
      const userCredential = await createUserWithEmailAndPassword(
        auth,
        email,
        password,
      );
      await updateProfile(userCredential.user, {        //요거 displayName을 받기위한 로직
        displayName: nickname,                             //아래 인풋태그에서 받을 닉네임을 연결
      });                                                         

      alert("회원가입 완료되었습니다.");   //얼럿을 추가해서 반응성추가
      setEmail("");                                   //인풋에 써져있는것을 초기화하기위한 셋
      setPassword("");
    } catch (error) {
      console.error(error);
      alert("이메일형식이어야합니다 .비밀번호는 6자 이상이어야합니다.");
    }                                                         //요것도 잘되는지 얼럿
  };
  const signIn = async (event) => {
    event.preventDefault();
    try {
      const userCredential = await signInWithEmailAndPassword(
        auth,
        email,                                      //회원가입을 위한 함수를 어웨이트로 기다려서 정보를 받고
        password,
      );
      console.log(userCredential);
      alert("로그인 되었습니다.");
      const user = userCredential.user;
      const loginUser = {
        id: user.uid,
        email: user.email,
        isdone: true,
        nickname: user.displayName,
      };

      setUsers(loginUser);     //라우터 .js에 있는 user를 로그인 유저의 객체로 바꿔준다.
                                              //isdone을 초기값을 false로 줬는데 이때 로그인되면 true바뀐다.
      navigate("/mypage");    //로그인과 동시에 마이페이지로 이동 추후에 홈으로 바꿔야지
    } catch (error) {
      console.error(error);
      alert("이메일 비밀번호를 확인해주세요");
    }
  };
  const logOut = async (event) => {
    event.preventDefault();
    await signOut(auth);
    alert("로그아웃되었습니다.");

    navigate("/mypage");
    setUsers({ isdone: false });     //로그아웃되면 유저스의 isdone을 false로 다시 바꿈
  };

  return (
    <BodyWrapper>
      <LoginWrapper>
        <h2>로그인페이지</h2>
        <form>
          <div>
            <label>닉네임 : </label>        //닉네임 인풋포함한 디브만 추가
            <input
              type="text"
              value={nickname}
              name="displayName"
              onChange={onChange}
              required
            />
          </div>
          <div>
            <label>이메일 : </label>
            <input
              type="email"
              value={email}
              name="email"
              onChange={onChange}
              required
            />
          </div>
          <div>
            <label>비밀번호 : </label>
            <input
              type="password"
              value={password}
              name="password"
              onChange={onChange}
              required
            />
          </div>
          <button onClick={signUp}>회원가입</button>
          <button onClick={signIn}>로그인</button>
          <button onClick={logOut}>로그아웃</button>
        </form>
      </LoginWrapper>
    </BodyWrapper>
  );
}

const Div = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  height: 800px;
`;
const LoginWrapper = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #fff1f0;
  border: 1px solid black;
  border-radius: 5px;
  width: 400px;
  height: 300px;
  gap: 20px;
  & h2 {
    font-size: 30px;
  }
  & button {
    background-color: black;
    color: white;
  }
`;
const BodyWrapper = styled.div``;

 

아래는 Header.jsx 파일이다. 맨위에 Router.jsx 에서 마이페이지로 유저스를 프롭스 해줬는데

마이페이지는 프롭스 중간다리일 뿐이라 프롭스 드릴링으로 헤더 작스 파일로 프롭스 해줬다.

import React from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
export default function Header({  users }) {             //유저스를 프롭스로 받는다.
  return (
    <>
      <HeadWrapper>
        <BtnWrapper>
          {users.isdone === false ? (               //삼항 연산자를 써봤는데 유저스 객체의
            <Link to={"/register"}>                      //isdone이 폴스이면 로그인 버튼을 보여주고
              <Button>로그인</Button>{" "}
            </Link>
          ) : (
            <>
              <h1>{users.nickname}님 환영합니다.</h1>   //트루이면 누구누구님 환영합니다.
              <Link to={"/register"}>                                //를 보여주는 로직
                <Button>로그아웃</Button>{" "}           //라우터 작스에서 프롭스 받은 users가
              </Link>                                            //잘 내려왔다. 동일하게 유저스에서
            </>                                               //이메일과 아이디도 받을수 있다. 
          )}                                                 //users.id  //users.email
        </BtnWrapper>
      </HeadWrapper>
    </>
  );
}

const HeadWrapper = styled.div`
  display: flex;
  justify-content: flex-end;
  align-items: center;
  height: 100px;
`;

const Button = styled.button`
  background-color: black;
  color: white;
  font-size: large;
  border-radius: 5px;
  margin-right: 50px;
`;

const BtnWrapper = styled.div`
  background-color: yellow;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100px;
  width: 200px;
`;

파이어베이스 스토리지는 내일 할수 있으면 하고 위에거 브라우저 구성 조금 바꾸고 하면 될듯하다.