Skip to content

Commit

Permalink
[Fix] 이메일 로그인 관련 오류 수정
Browse files Browse the repository at this point in the history
- 이메일 로그인 시 로그인 상태 제대로 갱신되지 않는 문제 수정 (로그인 관련 전역상태 코드 수정)
- 로그인 상태로 새로고침 했을 때 로그인 해제되는 부분 수정
- 로그아웃 시 로컬 스토리지에 액세스 토큰 계속 남아있던 문제 해결

Issues #94
  • Loading branch information
novice1993 committed Sep 12, 2023
1 parent ea57823 commit 0a9341c
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 152 deletions.
22 changes: 11 additions & 11 deletions client/src/components/Logins/EmailLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import axios from "axios";
import styled from "styled-components";
import React, { useState } from "react";
import { setLoginState } from '../../reducer/member/loginSlice';
import { useDispatch } from 'react-redux';
import { setLoginState } from "../../reducer/member/loginSlice";
import { useDispatch } from "react-redux";

// 이메일 로그인 모달 컴포넌트
const EmailLoginModal: React.FC<EmailLoginModalProps> = ({ onClose, onLogin }) => {
Expand Down Expand Up @@ -40,18 +40,18 @@ const EmailLoginModal: React.FC<EmailLoginModalProps> = ({ onClose, onLogin }) =
password,
});
if (response.status === 200) {
const authToken = response.headers['authorization'];
const authToken = response.headers["authorization"];
console.log(authToken);
const refreshToken = response.headers['refresh'];

const refreshToken = response.headers["refresh"];

// 로그인 상태로 만들기
dispatch(setLoginState(true));
dispatch(setLoginState());

// 토큰들을 로컬 스토리지에 저장
if(authToken) localStorage.setItem('authToken', authToken);
if(refreshToken) localStorage.setItem('refreshToken', refreshToken);
if (authToken) localStorage.setItem("authToken", authToken);
if (refreshToken) localStorage.setItem("refreshToken", refreshToken);

onLogin();
onClose();
} else {
Expand Down
77 changes: 35 additions & 42 deletions client/src/components/Logins/GoogleSignin.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
import React from 'react';
import { GoogleOAuthProvider, GoogleLogin, useGoogleOneTapLogin } from '@react-oauth/google';
import { useDispatch } from 'react-redux';
import { setLoginState } from '../../reducer/member/loginSlice';
import React from "react";
import { GoogleOAuthProvider, GoogleLogin, useGoogleOneTapLogin } from "@react-oauth/google";
import { useDispatch } from "react-redux";
import { setLoginState } from "../../reducer/member/loginSlice";

const GoogleSignInComponent: React.FC = () => {

const dispatch = useDispatch(); // Redux의 dispatch 함수를 사용하기 위해 가져옵니다.

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleSuccess = (credentialResponse: any) => {
console.log(credentialResponse);

const token = credentialResponse.token; // 실제 응답에서 토큰의 경로가 어떤지 확인하고 수정해야 합니다.
localStorage.setItem('authToken', token); // 토큰을 localStorage에 저장

// 로그인 성공 시 전역 상태를 업데이트합니다.
dispatch(setLoginState({
memberId: credentialResponse.memberId, // memberId는 예시입니다. 실제 값에 맞게 수정해야 합니다.
isLoggedIn: 1,
}));
};

const handleError = () => {
console.log('Login Failed');
};

// One-tap 로그인 (선택적)
useGoogleOneTapLogin({
onSuccess: handleSuccess,
onError: handleError,
});

return (
<GoogleOAuthProvider clientId="
690344785644-2oj84rcukd2rhu3o56gbq6rahap16m37.apps.googleusercontent.com">
<GoogleLogin
onSuccess={handleSuccess}
onError={handleError}
useOneTap
/>
</GoogleOAuthProvider>
);
const dispatch = useDispatch(); // Redux의 dispatch 함수를 사용하기 위해 가져옵니다.

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleSuccess = (credentialResponse: any) => {
console.log(credentialResponse);

const token = credentialResponse.token; // 실제 응답에서 토큰의 경로가 어떤지 확인하고 수정해야 합니다.
localStorage.setItem("authToken", token); // 토큰을 localStorage에 저장

// 로그인 성공 시 전역 상태를 업데이트합니다.
dispatch(setLoginState());
};

const handleError = () => {
console.log("Login Failed");
};

// One-tap 로그인 (선택적)
useGoogleOneTapLogin({
onSuccess: handleSuccess,
onError: handleError,
});

return (
<GoogleOAuthProvider
clientId="
690344785644-2oj84rcukd2rhu3o56gbq6rahap16m37.apps.googleusercontent.com"
>
<GoogleLogin onSuccess={handleSuccess} onError={handleError} useOneTap />
</GoogleOAuthProvider>
);
};

export default GoogleSignInComponent;

15 changes: 6 additions & 9 deletions client/src/components/StockOrderSection/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,20 @@ const marketType: string = "코스피";

// dummyData
import dummyLogo from "../../asset/CentralSectionMenu-dummyImg.png";
import { useState } from "react";

const StockOrderSection = () => {
const dispatch = useDispatch();
const isLogin = useSelector((state: StateProps) => state.login);
const companyId = useSelector((state: StateProps) => state.companyId);
const stockOrderSet = useSelector((state: StateProps) => state.stockOrderSet);

// 🔴 로그인 구현될 때까지 임시
const [login, setLogin] = useState(true);
if (companyId === 10000000) {
setLogin(true);
}
//

const { stockInfo, stockInfoLoading, stockInfoError } = useGetStockInfo(companyId);
const { stockPrice, stockPriceLoading, stockPriceError } = useGetStockData(companyId);

console.log(isLogin);
const localData = localStorage.getItem("authToken");
console.log(localData);

// 주식주문 창 닫기
const handleStockOrderClose = () => {
dispatch(stockOrderClose());
Expand Down Expand Up @@ -71,7 +68,7 @@ const StockOrderSection = () => {
&#10005;
</button>
</UpperBar>
{login ? (
{isLogin === 1 ? (
<>
<StockName>
<img className="CorpLogo" src={dummyLogo} />
Expand Down
1 change: 1 addition & 0 deletions client/src/models/stateProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export interface StateProps {
companyId: number;
stockOrderVolume: number;
decisionWindow: boolean;
login: number;
}
91 changes: 32 additions & 59 deletions client/src/page/MainPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// /client/src/pages/MainPage.tsx
import { useState, useCallback } from "react";
import { useSelector } from "react-redux";
import { useState, useEffect, useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
import styled from "styled-components";
import LogoutHeader from "../components/Headers/LogoutHeader";
import LoginHeader from "../components/Headers/LoginHeader";
Expand All @@ -20,6 +19,10 @@ import ProfileModal from "../components/Profile/profileModal";
import { StateProps } from "../models/stateProps";
import { TabContainerPage } from "./TabPages/TabContainerPage";

// 🔴 로그아웃 관련 action 함수
import { setLogoutState } from "../reducer/member/loginSlice";
import { setLoginState } from "../reducer/member/loginSlice";

const MainPage = () => {
const expandScreen = useSelector((state: StateProps) => state.expandScreen);

Expand Down Expand Up @@ -56,8 +59,7 @@ const MainPage = () => {
setEmailSignupModalOpen(false);
}, []);

const [isEmailVerificationModalOpen, setEmailVerificationModalOpen] =
useState(false);
const [isEmailVerificationModalOpen, setEmailVerificationModalOpen] = useState(false);

// 이메일 인증 모달을 열 때 사용자가 입력한 이메일을 저장하도록 변경
const openEmailVerificationModal = useCallback((enteredEmail: string) => {
Expand All @@ -70,8 +72,7 @@ const MainPage = () => {
setEmailVerificationModalOpen(false);
}, []);

const [isPasswordSettingModalOpen, setPasswordSettingModalOpen] =
useState(false);
const [isPasswordSettingModalOpen, setPasswordSettingModalOpen] = useState(false);

const openPasswordSettingModal = useCallback(() => {
setEmailVerificationModalOpen(false); // 이메일 인증 모달 닫기
Expand All @@ -91,12 +92,23 @@ const MainPage = () => {
setWelcomeModalOpen(false);
}, []);

// 🔴 로그인 지역 상태 제거 → 전역 상태로 대체 (지역 상태 관련된 코드 싹 다 지워야함... -> 전역 상태 만들었으니 전역 상태로 활용)
const dispatch = useDispatch();
const isLogin = useSelector((state: StateProps) => state.login);
const [isLoggedIn, setIsLoggedIn] = useState(false); // 로그인 상태 관리

useEffect(() => {
const authToken = localStorage.getItem("authToken");

if (authToken !== null) {
dispatch(setLoginState());
}
}, []);

//프로필 모달 열고닫는 매커니즘
const openProfileModal = useCallback(() => {
setProfileModalOpen(true);
}, []);
}, []);

const [isLoginConfirmationModalOpen, setLoginConfirmationModalOpen] = useState(false);

Expand All @@ -110,78 +122,40 @@ const MainPage = () => {
setIsLoggedIn(true);
};

const [selectedMenu, setSelectedMenu] = useState<"관심목록" | "투자목록">(
"투자목록"
); // Default menu is 관심목록
const [selectedMenu, setSelectedMenu] = useState<"관심목록" | "투자목록">("투자목록"); // Default menu is 관심목록

const handleMenuChange = (menu: "관심목록" | "투자목록") => {
setSelectedMenu(menu);
};

// 🔴 로그 아웃 시 로컬데이터 토큰 제거
const handleLogout = () => {
setIsLoggedIn(false);
dispatch(setLogoutState());
localStorage.removeItem("authToken");
};

return (
<Container>

{isLoggedIn ? (
<LoginHeader onLogoutClick={handleLogout} onProfileClick={openProfileModal} />
) : (
<LogoutHeader onLoginClick={openOAuthModal} />
)}
{isLogin === 1 ? <LoginHeader onLogoutClick={handleLogout} onProfileClick={openProfileModal} /> : <LogoutHeader onLoginClick={openOAuthModal} />}

<Main>
<CompareChartSection />
{!expandScreen.left && (
<LeftSection>
{selectedMenu === "관심목록" ? (
<WatchList
key="watchlist"
currentListType={selectedMenu}
onChangeListType={handleMenuChange}
/>
) : (
<Holdings
currentListType={selectedMenu}
onChangeListType={handleMenuChange}
/>
)}
</LeftSection>
<LeftSection>{selectedMenu === "관심목록" ? <WatchList key="watchlist" currentListType={selectedMenu} onChangeListType={handleMenuChange} /> : <Holdings currentListType={selectedMenu} onChangeListType={handleMenuChange} />}</LeftSection>
)}
<CentralChart />
<StockOrderSection />
{!expandScreen.right && <TabContainerPage></TabContainerPage>}
</Main>
{isOAuthModalOpen && (
<OAuthLoginModal
onClose={closeOAuthModal}
onEmailLoginClick={openEmailLoginModal}
onEmailSignupClick={openEmailSignupModal}
onWatchListClick={() => handleMenuChange("관심목록")}
onHoldingsClick={() => handleMenuChange("투자목록")}
/>
<OAuthLoginModal onClose={closeOAuthModal} onEmailLoginClick={openEmailLoginModal} onEmailSignupClick={openEmailSignupModal} onWatchListClick={() => handleMenuChange("관심목록")} onHoldingsClick={() => handleMenuChange("투자목록")} />
)}

{isEmailLoginModalOpen && <EmailLoginModal onClose={closeEmailLoginModal} onLogin={handleLogin} />}
{isLoginConfirmationModalOpen && (
<LoginConfirmationModal onClose={handleLoginConfirmationClose} />
{isLoginConfirmationModalOpen && <LoginConfirmationModal onClose={handleLoginConfirmationClose} />}

)}

{isEmailSignupModalOpen && (
<EmailSignupModal
onClose={closeEmailSignupModal}
onRequestVerification={openEmailVerificationModal}
/>
)}
{isEmailVerificationModalOpen && (
<EmailVerificationModal
onClose={closeEmailVerificationModal}
onNextStep={openPasswordSettingModal}
initialEmail={userEmail}
/>
)}
{isEmailSignupModalOpen && <EmailSignupModal onClose={closeEmailSignupModal} onRequestVerification={openEmailVerificationModal} />}
{isEmailVerificationModalOpen && <EmailVerificationModal onClose={closeEmailVerificationModal} onNextStep={openPasswordSettingModal} initialEmail={userEmail} />}

{isPasswordSettingModalOpen && (
<PasswordSettingModal
Expand All @@ -196,9 +170,8 @@ const MainPage = () => {
closeWelcomeModal();
}}
/>
)}
{isProfileModalOpen && <ProfileModal onClose={() => setProfileModalOpen(false)} />}

)}
{isProfileModalOpen && <ProfileModal onClose={() => setProfileModalOpen(false)} />}
</Container>
);
};
Expand Down
28 changes: 13 additions & 15 deletions client/src/reducer/member/loginSlice.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import { createSlice } from '@reduxjs/toolkit';
import { createSlice } from "@reduxjs/toolkit";

const initialState: number = 0;

const loginSlice = createSlice({
name: 'login',
initialState: {
memberId: 0,
isLoggedIn: 1
},
name: "login",
initialState: initialState,
reducers: {
setLoginState: (state, action) => {
state.memberId = action.payload;
state.isLoggedIn = 1;
setLoginState: (state) => {
state = 1;
return state;
},
setLogoutState: (state) => {
state.memberId = 0;
state.isLoggedIn = 0;
state = 0;
return state;
},

}
},
});

export const { setLoginState, setLogoutState} = loginSlice.actions;
export default loginSlice.reducer;
export const { setLoginState, setLogoutState } = loginSlice.actions;
export const loginReducer = loginSlice.reducer;
11 changes: 0 additions & 11 deletions client/src/reducer/member/rootReducer.ts

This file was deleted.

Loading

0 comments on commit 0a9341c

Please sign in to comment.