https://console.firebase.google.com/
내가 추가하고자 하는 인증은 일단.
1. 이메일/비밀번호( 회원가입 시)
2. 구글 인증
3. 깃허브 인증
이렇게 추가할 예정이다.
그 중 이메일/비밀번호부터 해보겠음.,
1. 이메일/ 비밀번호 인증
현재 작업하고 있는 프로젝트에
firebase.js 파일에서 파이어베이스 관련 설정을 할거임
이미 기본 설정은 되어있고 여기에 인증 관련 초기 설정만 추가하면됨
하단에 파이어베이스 인증 코드를 추가한다.
getAuth 을 import한다.
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIRE_API,
authDomain: import.meta.env.VITE_FIRE_DOMAIN,
projectId: import.meta.env.VITE_FIRE_PROJECTID,
storageBucket: import.meta.env.VITE_FIRE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIRE_SENDERID,
appId: import.meta.env.VITE_FIRE_APPID,
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
//파이어베이스 인증
const auth = getAuth();
export { auth };
회원가입 테스트 시 state에 잘 저장되는지 확인한다.
이제 입력된 데이터를 가지고 파이어스토어에 인증유저에 추가한다.
import { auth } from "../../firebase";
const navigate = useNavigate(); //네비게이션
//회원가입 시 입력하는 유저 정보 저장
const onChange = (e) => {
const { name, value } = e.target;
if (name === "name") {
setName(value);
} else if (name === "email") {
setEmail(value);
} else if (name === "password") {
setPassword(value);
}
};
// 회원가입 버튼 클릭 시
const onSubmit = async (e) => {
e.preventDefault();
if (isLoading || name === "" || email === "" || password === "") return;
//회원가입 실행
try {
setLoading(true); //로딩시작
//유저정보
const credentials = await createUserWithEmailAndPassword(
auth,
email,
password
);
console.log(credentials.user); //유저 정보 출력
await updateProfile(credentials.user, {
displayName: name, //이름저장
});
navigate("/"); //회원가입 후 기본페이지로 이동
} catch (e) {
console.log(e);
} finally {
setLoading(false);
}
};
파이어 베이스에 저장
에러 시 출력되는 코드 수정한다.
//회원가입 실행
try {
setLoading(true); //로딩시작
//유저정보
const credentials = await createUserWithEmailAndPassword(
auth,
email,
password
);
console.log(credentials.user); //유저 정보 출력
await updateProfile(credentials.user, {
displayName: name, //이름저장
});
navigate("/"); //회원가입 후 기본페이지로 이동
} catch (e) {
if (e instanceof FirebaseError) setError(e.code);
} finally {
setLoading(false);
}
//에러 표시
const errorMessageToKorean = (error) => {
switch (error) {
case "auth/invalid-login-credentials":
case "auth/invalid-credential":
case "auth/user-not-found" || "auth/wrong-password":
return "이메일 혹은 비밀번호가 일치하지 않습니다.";
case "auth/email-already-in-use":
return "이미 사용 중인 이메일입니다.";
case "auth/weak-password":
return "비밀번호는 6글자 이상이어야 합니다.";
case "auth/network-request-failed":
return "네트워크 연결에 실패 하였습니다.";
case "auth/invalid-email":
return "잘못된 이메일 형식입니다.";
case "auth/internal-error":
return "잘못된 요청입니다.";
default:
return "에러가 발생했습니다.";
}
};
{error && (
<span style={{ color: "red", textAlign: "center", marginTop: "5%" }}>
{errorMessageToKorean(error)}
</span>
)}
<p>
이미 계정이 있습니까? <Link to="/user/login"> 로그인 </Link>
</p>
이미 계정이 있을 경우에는 로그인 link로 이동하게끔 걸어준다.
이 부분은 style 수정해야 함
로딩중일때는 가입중으로 버튼 바뀜
{/* 회원가입 로딩 표시 */}
{isLoading && (
<input className="loginBtn" type="submit" value="가입중" />
)}
{!isLoading && (
<input className="loginBtn" type="submit" value="회원가입" />
)}
그리고 Navbar.jsx에서는 로그아웃 li태그를 추가하여 로그아웃 기능을 추가할거고
현재 로그인 중인 유저의 경우에는 로그아웃만 표시
로그인 되지않은 유저의 경우 로그인/회원가입 표시
import React from "react";
import "./Navbar.css";
import { LuBookOpen } from "react-icons/lu";
import { Link } from "react-router-dom";
import { auth } from "../../firebase";
const Navbar = () => {
const navigate = useNavigate();
const user = auth.currentUser; //현재 접속 유저
//console.log(user);
//로그아웃 함수
const logOut = () => {
auth.signOut();
navigate("/");
};
return (
<>
<nav className="navbar">
<div className="nav_header">
<Link to="/">
<LuBookOpen />
Book
<span className="nav_market">Store</span>
</Link>
</div>
<div className="nav_list">
<ul>
{/* 현재 로그인 중인 유저가 아니면 */}
{!user && (
<>
<li>
<Link to="/user/join">회원가입</Link>
</li>
<li>
<Link to="/user/login">로그인</Link>
</li>
</>
)}
{/* 현재 로그인중이면*/}
{user && (
<>
<li>{user.displayName}님 환영합니다!</li>
<li onClick={logOut}>로그아웃</li>
</>
)}
</ul>
</div>
</nav>
</>
);
};
export default Navbar;
유저의 이름도 표시
로그인
import React, { useState } from "react";
import "./Login.css";
import { LuBookOpen } from "react-icons/lu";
import { FcGoogle } from "react-icons/fc";
import { Link, useNavigate } from "react-router-dom";
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "../../firebase";
import { FirebaseError } from "firebase/app";
const Login = () => {
const navigate = useNavigate();
const [isLoading, setLoading] = useState(false);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const onChange = (e) => {
//이벤트 객체를 분리함 ( target -> name/value )
//console.log(e);
const { name, value } = e.target;
if (name === "email") {
setEmail(value);
} else if (name === "password") {
setPassword(value);
}
};
const onSubmit = async (e) => {
e.preventDefault();
setError(""); //에러 초기화
if (isLoading || email === "" || password === "") return; //만약 이름,이메일,패스워드가 공백이면 리턴함
//로그인 실행
try {
setLoading(true); //로딩 시작
//유저정보
const credentials = await signInWithEmailAndPassword(
auth,
email,
password
);
console.log(credentials.user); // 유저 정보 출력
navigate("/"); //로그인 완료 후 기본 페이지로
} catch (e) {
if (e instanceof FirebaseError) {
setError(e.code, e.message);
}
} finally {
setLoading(false);
}
};
return (
<div className="formContainer">
<div className="logo">
<LuBookOpen />
Book
<span className="nav_market">Store</span>
</div>
<h1>로그인</h1>
<form onSubmit={onSubmit}>
<input
onChange={onChange}
name="email"
value={email}
type="email"
placeholder="이메일을 입력하세요..."
/>
<input
onChange={onChange}
value={password}
name="password"
type="password"
placeholder="비밀번호를 입력하세요..."
/>
<input
className="loginBtn"
type="submit"
value={isLoading ? "로딩중" : "로그인"}
/>
</form>
{error && (
<span style={{ color: "red", textAlign: "center", marginTop: "5%" }}>
{errorMessageToKorean(error)}
</span>
)}
<div className="googleLogin">
<FcGoogle />
</div>
<p>
계정이 없으신가요? <Link to="/user/join"> 가입하기 </Link>
</p>
</div>
);
};
export default Login;
//에러 표시
export const errorMessageToKorean = (error) => {
switch (error) {
case "auth/invalid-login-credentials":
case "auth/invalid-credential":
case "auth/user-not-found" || "auth/wrong-password":
return "이메일 혹은 비밀번호가 일치하지 않습니다.";
case "auth/email-already-in-use":
return "이미 사용 중인 이메일입니다.";
case "auth/weak-password":
return "비밀번호는 6글자 이상이어야 합니다.";
case "auth/network-request-failed":
return "네트워크 연결에 실패 하였습니다.";
case "auth/invalid-email":
return "잘못된 이메일 형식입니다.";
case "auth/internal-error":
return "잘못된 요청입니다.";
default:
return "에러가 발생했습니다.";
}
};
'FRONTEND > React' 카테고리의 다른 글
[React-BookStore] firebase 인증 추가 - 구글 /깃허브 (0) | 2023.12.12 |
---|---|
[React-BookStore] 구현하고자 하는 기능 및 오류 수정 과정 정리 (0) | 2023.12.12 |
[Nwitter-Fire] 호스팅 (1) | 2023.12.11 |
[Nwitter-Fire] 프로필 페이지 유저 아바타 / 프로필 업데이트/ 프로필 이름 수정 (1) | 2023.12.11 |
[Nwitter-Fire] 파이어 스토어 스토리지 사용설정 / 트윗 저장/이미지 저장 / 타임라인 생성 및 실시간 업데이트/ 트윗 삭제 (0) | 2023.12.08 |