2.Authentication
Updated:
1.Firebase Auth
- firebase auth 를 사용하려면 project 에 먼저 import 해줘야 함
// in firebase.js
// Firebase App (the core Firebase SDK) is always required and must be listed first
import firebase from "firebase/app";
// import firebase/auth
import "firebase/auth";
const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_DATABASE_URL,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGIN_ID,
appId: process.env.REACT_APP_APP_APP_ID,
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// authService 로 firebase.auth() 호출하는것을
export const authService = firebase.auth();
// in App.js
// {authService} 를 변수로 사용할 수 있게 됨
import React, { useState } from "react";
import useTitle from "@jacob-hooks/use-title";
import { authService } from "../fbase";
import AppRouter from "./Router";
function App() {
useTitle("Chat-app");
console.log(authService.currentUser);
// authService.currentUser 를 통해 로그인 되었는지 안되었는지 확인 할 수 있음 (로그인 안되어 있으면 null 이 return )
const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
return (
<>
<AppRouter isLoggedIn={isLoggedIn} />
<footer>© {new Date().getFullYear()} Jacob Ko</footer>
</>
);
}
export default App;
2.Login form
- Authentication 을 위해서 간단한 login form 을 만듬
import React, { useState } from "react";
const Auth = () => {
// set state email, password
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
// onchange to email, password
const onChange = (e) => {
const {
target: { name, value },
} = e;
if (name === "email") {
setEmail(value);
} else if (name === "password") {
setPassword(value);
}
};
// 기본적인 실행 (refresh 된 담에 url 에 value 값 나오는것) 하지 않기 위해 preventDefault()
const onSubmit = (e) => {
e.preventDefault();
};
return (
<>
<form onSubmit={onSubmit}>
<input
name="email"
type="email"
placeholder="Email"
required
value={email}
onChange={onChange}
/>
<input
name="password"
type="password"
placeholder="Password"
required
value={password}
onChange={onChange}
/>
<input type="submit" value="Log In" />
</form>
<div>
<button>Continue with Google</button>
<button>Continue with Github</button>
</div>
</>
);
};
export default Auth;
3.Creating account
- 이메일과 패스워드로 사용자 계정을 만들기
// in Auth.js
import React, { useState } from "react";
import { authService } from "../fbase";
const Auth = () => {
// set state email, password, newAccount
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [newAccount, setNewAccount] = useState(true);
// onchange to email, password
const onChange = (e) => {
const {
target: { name, value },
} = e;
if (name === "email") {
setEmail(value);
} else if (name === "password") {
setPassword(value);
}
};
// 기본적인 실행 (refresh 된 담에 url 에 value 값 나오는것) 하지 않기 위해 preventDefault()
const onSubmit = async (e) => {
e.preventDefault();
try {
let data;
if (newAccount) {
// create account
data = await authService.createUserWithEmailAndPassword(
email,
password
);
} else {
// log in
data = await authService.signInWithEmailAndPassword(email, password);
}
console.log(data);
} catch (error) {
console.log(error);
}
};
return (
<>
<form onSubmit={onSubmit}>
<input
name="email"
type="email"
placeholder="Email"
required
value={email}
onChange={onChange}
/>
<input
name="password"
type="password"
placeholder="Password"
required
value={password}
onChange={onChange}
/>
<input type="submit" value={newAccount ? "Create Account" : "Log In"} />
</form>
<div>
<button>Continue with Google</button>
<button>Continue with Github</button>
</div>
</>
);
};
export default Auth;
4.Log In
- setPersistence : 사용자들을 어떻게 기억할 것인지 선택할 수 있도록 해주는것
value
에 기본값은 local
로써 새로고침 하더라도 사용자의 정보는 계속 저장되서 로그인 상태를 유지 시켜주는것임
-
App 이 로드 될때 시간이 빠르게 일어나기 때문에firebase는 사용자가 로그인 되었는지 아닌지를 확인할 시간이 없게 된다 그래서 refresh 해도 여전히 로그인 정보가 남아 있게 됨
-
onAuthStateChanged : 사용자의 로그인 상태의 변화를 관찰하는 observer 를 추가시켜서 변화를 알아차려서 유저 상태에 변화가 있을 때 그 변화를 알아차리게 되는 것임 유저가 진짜로 로그아웃할 때도 발생하고 계정이 생성할 때도 trigger 되고 firebase 가 초기화 될때도 실행 됨 그리고 나서 다음에 로그인 되는 순간도 알아차리게 되는것임
- 그래서 실제로 로그인이 되었는지 안되었는지를 알 수 있게 됨. 이렇게 되면
authService.currentUser
에서는 실제로 로그인된 건지 로그아웃한 건지 잘 모르기 때문임
// useEffect 에 mount 가 변화가 있는지를 듣고 있는 경우가 됨. 누군가가 create account 를 클릭하거나 또는 log in 을 눌렀거나 아니면 이미 로그인 되어 있어서 firebase 는 스스로 초기화하는 것을 끝냈기 때문임
const [init, setInit] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
authService.onAuthStateChanged((user) => {
if (user) {
setIsLoggedIn(true);
} else {
setIsLoggedIn(false);
}
// 마지막에 setInit(true) 을 해줘서 init 이 false 라면 router 를 숨길것이기 때문에 true 를 해줌
setInit(true)
});
5.Social Login
- signInWithPopup : social 로그인을 위한 popup 창 설정
// Social login function
const onSocialClick = async (e) => {
const {
target: { name },
} = e;
let provider;
if (name === "google") {
provider = new firebaseInstance.auth.GoogleAuthProvider();
} else if (name === "github") {
provider = new firebaseInstance.auth.GithubAuthProvider();
}
const data = await authService.signInWithPopup(provider);
console.log(data);
};
<div>
<button onClick={onSocialClick} name="google">
Continue with Google
</button>
<button onClick={onSocialClick} name="github">
Continue with Github
</button>
</div>;
6.Log out
- sinOut : 로그아웃 상태로 만들어 줌
const onLogOutClick = () => authService.signOut();
return (
<div>
<button onClick={onLogOutClick}>Log Out</button>
</div>
);
- 근데 만약 로그아웃 되고 redirect 를 안해주면 그 해당 페이지에 그대로 남아 있기 때문에 react-router-dom 의 redirect 을 사용해서 초기화면 “/” 으로 이동하게 함
<>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/profile">
<Profile />
</Route>
<Redirect from="*" to="/" />
</>
- redirect 방법말고 router hook 의 useHistory 을 사용해서 초기화면으로 이동 시켜 줄 수 있음
const history = useHistory();
const onLogOutClick = () => {
authService.signOut();
history.push("/");
};
return (
<div>
<button onClick={onLogOutClick}>Log Out</button>
</div>
);
🔶 🔷 📌 🔑
Reference
- normad corder firebase - https://nomadcoders.co/nwitter/lobby
Leave a comment