From 3cf02589c128a9164d2c569f46065c1e2844d32c Mon Sep 17 00:00:00 2001 From: hwna00 Date: Tue, 26 Sep 2023 02:12:28 +0900 Subject: [PATCH] =?UTF-8?q?Feat(user):=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EA=B3=BC=EC=A0=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구글 로그인 삭제 - useUser훅 삭제 및 onAuthStateChaneged 도입 - 이메일 지속성을 'local'로 설정 ref: #67 --- packages/apps/user/firebase.js | 41 +++++++++---------- packages/apps/user/src/api.js | 7 ++-- .../apps/user/src/components/Root/Root.js | 33 ++++++++++----- packages/apps/user/src/hooks/useUser.js | 16 -------- .../apps/user/src/views/Auth/LogIn/LogIn.js | 13 ++++-- packages/server/controllers/authController.js | 11 +++-- packages/server/index.js | 4 +- 7 files changed, 63 insertions(+), 62 deletions(-) delete mode 100644 packages/apps/user/src/hooks/useUser.js diff --git a/packages/apps/user/firebase.js b/packages/apps/user/firebase.js index 173cf720..d3c46eb6 100644 --- a/packages/apps/user/firebase.js +++ b/packages/apps/user/firebase.js @@ -2,9 +2,10 @@ import { getDownloadURL, getStorage, ref, uploadBytes } from 'firebase/storage'; import { getAuth, signInWithEmailAndPassword, - GoogleAuthProvider, - signInWithPopup, createUserWithEmailAndPassword, + signInWithCustomToken, + setPersistence, + browserLocalPersistence, } from 'firebase/auth'; import { initializeApp } from 'firebase/app'; @@ -20,9 +21,8 @@ const firebaseConfig = { }; const app = initializeApp(firebaseConfig); -const auth = getAuth(app); const storage = getStorage(app); -const provider = new GoogleAuthProvider(); +export const auth = getAuth(app); export const uploadBlob = async (blob, email) => { const storageRef = ref(storage, `${email}/profileImg.png`); @@ -51,25 +51,22 @@ export const fbSignUp = async data => { } }; -export const fbLogIn = async data => { +export const fbEmailLogIn = async data => { + await setPersistence(auth, browserLocalPersistence); const { email, password } = data; - const isUserExist = true; - - if (!isUserExist) { - // TODO: 존재하지 않는 회원입니다 알림 발송 - } else { - const userCredential = await signInWithEmailAndPassword( - auth, - email, - password, - ); - console.log(userCredential); - console.log(userCredential._tokenResponse); - // TODO: email을 가지는 user 정보를 DB에서 가져온다. - - // TODO: CASE1. 이미 존재하는 경우 -> 경고알림 or 바로 로그인 - // TODO: CASE2. 존재하지 않는 경우 -> 회원가입 진행 + try { + const { user } = await signInWithEmailAndPassword(auth, email, password); + return user; + } catch (error) { + console.log(error); } }; -export const googleLogin = () => signInWithPopup(auth, provider); +export const fbTokenLogin = async token => { + try { + const { user } = await signInWithCustomToken(token); + return user; + } catch (error) { + console.log(error); + } +}; diff --git a/packages/apps/user/src/api.js b/packages/apps/user/src/api.js index b9c4a612..f992c9e4 100644 --- a/packages/apps/user/src/api.js +++ b/packages/apps/user/src/api.js @@ -8,12 +8,13 @@ const instance = axios.create({ export const createUser = () => {}; -export const getMe = async () => { - const { user } = await instance.get(`/users/me`); +export const getMe = async email => { + const { user } = await instance.get(`/users/me?email=${email}`); + if (!user) { // TODO: 해당 유저가 존재하지 않는 경우에 대한 처리 } else { - // return user + // return { ...user, profileImg: getUserImage(email) }; return { name: '하철환', profileImg: getUserImage(), diff --git a/packages/apps/user/src/components/Root/Root.js b/packages/apps/user/src/components/Root/Root.js index 230640f9..b7b9bc61 100644 --- a/packages/apps/user/src/components/Root/Root.js +++ b/packages/apps/user/src/components/Root/Root.js @@ -1,21 +1,32 @@ -import { Outlet, useNavigate } from 'react-router-dom'; -import { Box, Text } from '@chakra-ui/react'; +import { Navigate, Outlet } from 'react-router-dom'; +import { Box } from '@chakra-ui/react'; import StatusBar from '../StatusBar/StatusBar'; import SideBar from '../SideBar/SideBar'; +import { auth } from '../../../firebase'; +import { onAuthStateChanged } from 'firebase/auth'; +import { useState } from 'react'; const Root = function () { - const navigate = useNavigate(); - const userLoading = false; - const user = { - username: '하철환', - }; + const [isLoading, setIsLoading] = useState(true); + const [isLoggedIn, setIsLoggedIn] = useState(false); + + onAuthStateChanged(auth, user => { + setIsLoading(false); + if (user) { + setIsLoggedIn(true); + //TODO: DB에서 정보 요청 및 store에 저장 + } else { + //TODO: store 정보 삭제 + setIsLoading(false); + } + }); return ( <> - {userLoading ? ( - Loading.. - ) : user ? ( + {isLoading ? ( + 'loading...' + ) : isLoggedIn ? ( <> @@ -24,7 +35,7 @@ const Root = function () { ) : ( - navigate('/auth/log-in') + )} ); diff --git a/packages/apps/user/src/hooks/useUser.js b/packages/apps/user/src/hooks/useUser.js deleted file mode 100644 index 2e1f143f..00000000 --- a/packages/apps/user/src/hooks/useUser.js +++ /dev/null @@ -1,16 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; - -import { getMe } from '../api'; - -const useUser = () => { - const { isLoading, data, isError } = useQuery(['me'], getMe, { - retry: false, - }); - return { - userLoading: isLoading, - user: data, - isLoggedIn: !isError, - }; -}; - -export default useUser; diff --git a/packages/apps/user/src/views/Auth/LogIn/LogIn.js b/packages/apps/user/src/views/Auth/LogIn/LogIn.js index 03e4f46e..7994a884 100644 --- a/packages/apps/user/src/views/Auth/LogIn/LogIn.js +++ b/packages/apps/user/src/views/Auth/LogIn/LogIn.js @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react'; -import { Link as ReactRouterLink } from 'react-router-dom'; +import { Link as ReactRouterLink, useNavigate } from 'react-router-dom'; import { FaUserAlt, FaLock } from 'react-icons/fa'; import { AiFillGoogleCircle, AiFillTwitterCircle } from 'react-icons/ai'; import { useForm } from 'react-hook-form'; @@ -22,7 +22,7 @@ import { } from '@chakra-ui/react'; import NaverLoginButton from '../../../components/NaverLoginButton/NaverLoginButton'; -import { fbLogIn } from '../../../../firebase'; +import { fbEmailLogIn } from '../../../../firebase'; function LogIn() { const [showPassword, setShowPassword] = useState(false); @@ -30,6 +30,7 @@ function LogIn() { setShowPassword(!showPassword); }, [showPassword]); + const navigate = useNavigate(); const { register, handleSubmit, @@ -37,7 +38,13 @@ function LogIn() { } = useForm(); const onSubmit = function (data) { - fbLogIn(data); + fbEmailLogIn(data).then(user => { + if (user) { + navigate('/'); + } else { + //TODO: 상황에 맞는 알림 전송하기 ex. 존재하지 않는 사용자입니다. + } + }); }; return ( diff --git a/packages/server/controllers/authController.js b/packages/server/controllers/authController.js index ea1a5936..712fbdb6 100644 --- a/packages/server/controllers/authController.js +++ b/packages/server/controllers/authController.js @@ -19,16 +19,15 @@ const getNaverAuthApiUri = (code, state) => { const fbCreateCustomToken = async uid => { return await fbAdmin.auth().createCustomToken(uid); +}; - // then(customToken => { - // console.log(customToken); - // return customToken; - // }).catch(error => { - // console.log('Error creating custom token:', error); - // }); +const fbTokenLogin = token => { + console.log(token); + fbAdmin.auth(); }; module.exports = { getNaverAuthApiUri, fbCreateCustomToken, + fbTokenLogin, }; diff --git a/packages/server/index.js b/packages/server/index.js index 7538eb02..b4c3c618 100644 --- a/packages/server/index.js +++ b/packages/server/index.js @@ -4,6 +4,7 @@ const axios = require('axios'); const db = require('./config/db'); const { fbCreateCustomToken, + fbTokenLogin, getNaverAuthApiUri, } = require('./controllers/authController'); @@ -44,8 +45,9 @@ app.get('/api/auth/naver-callback', async (req, res) => { } catch { //TODO: email 중복이 발생할 경우 DB에 정보를 저장하지 않음 } finally { - fbCreateCustomToken(user.id).then(token => console.log(token)); + fbCreateCustomToken(user.id).then(token => fbTokenLogin(token)); + //TODO: 토큰을 프론트엔드로 전송 res.redirect('http://localhost:8080/auth/callback'); } });