트위터 클론 코딩 #2 Authentication
노마드 코더의 트위터 클론 코딩 강의를 듣고 정리한 강의노트입니다.
2.0 Using Firebase Auth / Firebase 인증 사용하기
특정 폴더 기준으로 상대 경로로 import 하는 방법
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
Firebase 설정 수정
인증 관련 값을 가져오기 위해 Firebase 설정 수정
⚠️ 강의 영상 이후로 firebase가 v9.0으로 업데이트하면서 기존 코드와 호환이 안되는 경우가 있어서 v9.0를 사용하는 경우 아래 코드로 진행
// Import the functions you need from the SDKs you need
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
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_ID,
}
// Initialize Firebase
const app = initializeApp(firebaseConfig)
export const authService = getAuth()
2.1 Login Form part One / 로그인 양식 첫번째
Firebase 인증에서 로그인 제공 업체를 다음과 같이 설정
Github의 경우 로그인 후 Developer settings에 들어가서 OAuth Application
을 생성하여 client id
와 secret key
를 넣어야 함
로그인 양식
하나의 onChange
이벤트 핸들러를 이용해서 email
과 password
입력을 다룰 수 있도록 코드를 구성
import React, { useState } from 'react'
const Auth = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const handleOnChange = (e) => {
const {
target: { name, value },
} = e
console.log(name)
if (name === 'email') {
setEmail(value)
} else if (name === 'password') {
setPassword(value)
}
}
const handleOnSubmit = (e) => {
e.preventDefault();
}
return (
<div>
<form onSubmit={handleOnSubmit}>
<input name="email" type="text" placeholder="Email" required value={email} onChange={handleOnChange} />
<input
name="password"
type="password"
placeholder="Password"
required
value={password}
onChange={handleOnChange}
/>
<input type="sumbit" valeu="Log In" />
</form>
<div>
<button>Continue with Google</button>
<button>Continue with Github</button>
</div>
</div>
)
}
export default Auth
2.2 Recap / 복습하기
onSubmit에서 preventDefault를 하는 이유?
기본적으로 type=submit
의 input
요소는 클릭 시 값에 해당하는 쿼리 스트링을 만들어서 해당 URL로 이동하는 동작을 한다. 하지만, SPA의 작동 방식과는 어울리지 않아서 이러한 기본 동작을 막는 것이 필요한데 그 때 필요한 것이 preventDefault
로 특정 이벤트의 기본 동작을 막아주는 역할을 한다.
2.3 Creating Account / 계정 생성하기
firebase.auth.EmailAuthProvider
를 사용할 예정
⚠️ 강의 코드와 달리 v9.0 버전에 맞춰서 수정해야할 부분이 있습니다.
import { authService } from 'fbase'
import React, { useState } from 'react'
import { createUserWithEmailAndPassword, signInWithEmailAndPassword } from 'firebase/auth';
const Auth = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [newAccount, setNewAccount] = useState(true)
const handleOnChange = (e) => {
const {
target: { name, value },
} = e
if (name === 'email') {
setEmail(value)
} else if (name === 'password') {
setPassword(value)
}
}
const handleOnSubmit = async (e) => {
e.preventDefault();
try{
let data;
if(newAccount){
data = await createUserWithEmailAndPassword(authService, email, password)
} else {
data = await signInWithEmailAndPassword(authService, email, password)
}
console.log(data);
} catch(error){
console.error(error)
}
}
return (
<div>
<form onSubmit={handleOnSubmit}>
<input name="email" type="text" placeholder="Email" required value={email} onChange={handleOnChange} />
<input
name="password"
type="password"
placeholder="Password"
required
value={password}
onChange={handleOnChange}
/>
<input type="submit" value={newAccount ? "Create Account" : "Log In"} />
</form>
<div>
<button>Continue with Google</button>
<button>Continue with Github</button>
</div>
</div>
)
}
export default Auth
"Create Account"를 하게 되면, 계정이 생성되고 해당 계정으로 로그인 상태가 된다. (구글 크롬 > Application 탭 > IndexedDB > firebase~ 에서 확인 가능)
2.4 Log In / 로그인
현재 회원가입을 할 것인지 로그인을 할 것인지 토글하는 버튼 추가
2.5 Social Login / 소셜 로그인
⚠️ Firebase v9.0 코드
import { auth } from 'fbase'
import React, { useState } from 'react'
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
GoogleAuthProvider,
GithubAuthProvider,
signInWithPopup,
} from '@firebase/auth'
const Auth = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [newAccount, setNewAccount] = useState(true)
const [error, setError] = useState('')
const handleOnChange = (e) => {
const {
target: { name, value },
} = e
if (name === 'email') {
setEmail(value)
} else if (name === 'password') {
setPassword(value)
}
}
const handleOnSubmit = async (e) => {
e.preventDefault()
try {
let data
if (newAccount) {
data = await createUserWithEmailAndPassword(auth, email, password)
} else {
data = await signInWithEmailAndPassword(auth, email, password)
}
console.log(data)
} catch (error) {
setError(error.message)
}
}
const toggleAccount = () => {
setNewAccount((prev) => !prev)
}
const handleOnSocialClick = async (e) => {
const {
target: { name },
} = e
let provider
if (name === 'google') {
provider = new GoogleAuthProvider()
} else if (name === 'github') {
provider = new GithubAuthProvider()
}
const data = await signInWithPopup(auth, provider)
}
return (
<div>
<form onSubmit={handleOnSubmit}>
<input name="email" type="text" placeholder="Email" required value={email} onChange={handleOnChange} />
<input
name="password"
type="password"
placeholder="Password"
required
value={password}
onChange={handleOnChange}
/>
<input type="submit" value={newAccount ? 'Create Account' : 'Sign In'} />
{error}
</form>
<span onClick={toggleAccount}>{newAccount ? 'Sign In' : 'Create Account'}</span>
<div>
<button name="google" onClick={handleOnSocialClick}>
Continue with Google
</button>
<button name="github" onClick={handleOnSocialClick}>
Continue with Github
</button>
</div>
</div>
)
}
export default Auth
2.6 Log Out / 로그아웃
import { auth } from 'fbase'
import React from 'react'
import { useHistory } from 'react-router'
const Profile = () => {
const history = useHistory()
const handleOnLogOutClick = () => {
auth.signOut()
history.push('/')
}
return (
<>
<button onClick={handleOnLogOutClick}>Log Out</button>
</>
)
}
export default Profile
'노마드코더 > 트위터 클론코딩' 카테고리의 다른 글
트위터 클론 코딩 #3 Nweeting (2) | 2021.10.01 |
---|---|
트위터 클론 코딩 #0 Introduction ~ #1 Set up (0) | 2021.09.08 |
댓글
이 글 공유하기
다른 글
-
트위터 클론 코딩 #3 Nweeting
트위터 클론 코딩 #3 Nweeting
2021.10.01 -
트위터 클론 코딩 #0 Introduction ~ #1 Set up
트위터 클론 코딩 #0 Introduction ~ #1 Set up
2021.09.08