해결된 질문
작성
·
447
0
const token = await EncryptedStorage.getItem('refreshToken');
if (!token) {
SplashScreen.hide(); // here
return;
}
...
} finally {
SplashScreen.hide(); // here
}
};
getTokenAndRefresh();
}, [dispatch]);
강의 따라서 SplashScreen.hide() 잘 해주었는데,
이 상태에서 멈추고 갑자기 back 서버 터미널이 무한 로딩되는데... back 서버를 껐다가 다시 켰는데 로그인이 되어있으면 안되는데 되어있는 상황입니다
import * as React from 'react';
import {useEffect} from 'react';
import {useSelector} from 'react-redux';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Settings from './src/pages/Settings';
import Orders from './src/pages/Orders';
import Delivery from './src/pages/Delivery';
import SignIn from './src/pages/SignIn';
import SignUp from './src/pages/SignUp';
import {RootState} from './src/store/reducer';
import useSocket from './src/hooks/useSocket';
import EncryptedStorage from 'react-native-encrypted-storage';
import axios, {Axios, AxiosError} from 'axios';
import Config from 'react-native-config';
import userSlice from './src/slices/user';
import {useAppDispatch} from './src/store';
import {Alert} from 'react-native';
import orderSlice from './src/slices/order';
import usePermissions from './src/hooks/usePermissions';
import SplashScreen from 'react-native-splash-screen';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
export type LoggedInParamList = {
Orders: undefined;
Settings: undefined;
Delivery: undefined;
Complete: {orderId: string};
};
export type RootStackParamList = {
SignIn: undefined;
SignUp: undefined;
};
const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator<RootStackParamList>();
function AppInner() {
const dispatch = useAppDispatch();
const isLoggedIn = useSelector((state: RootState) => !!state.user.email);
const [socket, disconnect] = useSocket();
usePermissions();
useEffect(() => {
axios.interceptors.response.use(
response => {
// console.log(response);
return response;
},
async error => {
const {
config,
response: {status},
} = error;
if (status === 419) {
if (error.response.data.code === 'expired') {
const originalRequest = config;
const refreshToken = await EncryptedStorage.getItem('refreshToken');
// token refresh 요청
const {data} = await axios.post(
`${Config.API_URL}/refreshToken`, // token refresh api
{},
{headers: {authorization: `Bearer ${refreshToken}`}},
);
// 새로운 토큰 저장
dispatch(userSlice.actions.setAccessToken(data.data.accessToken));
originalRequest.headers.authorization = `Bearer ${data.data.accessToken}`;
// 419로 요청 실패했던 요청 새로운 토큰으로 재요청
return axios(originalRequest);
}
}
return Promise.reject(error);
},
);
}, [dispatch]);
useEffect(() => {
const callback = (data: any) => {
console.log(data);
dispatch(orderSlice.actions.addOrder(data));
};
if (socket && isLoggedIn) {
socket.emit('acceptOrder', 'hello');
socket.on('order', callback);
}
return () => {
if (socket) {
socket.off('order', callback);
}
};
}, [dispatch, isLoggedIn, socket]);
useEffect(() => {
if (!isLoggedIn) {
console.log('!isLoggedIn', !isLoggedIn);
disconnect();
}
}, [isLoggedIn, disconnect]);
// 앱 실행 시, 토큰 있으면 로그인하는 코드
useEffect(() => {
const getTokenAndRefresh = async () => {
try {
const token = await EncryptedStorage.getItem('refreshToken');
if (!token) {
SplashScreen.hide();
return;
}
const response = await axios.post(
`${Config.API_URL}/refreshToken`,
{},
{
headers: {
authorization: `Bearer ${token}`,
},
},
);
dispatch(
userSlice.actions.setUser({
name: response.data.data.name,
email: response.data.data.email,
accessToken: response.data.data.accessToken,
}),
);
} catch (error) {
console.error(error);
if (((error as AxiosError).response?.data as any).code === 'expired') {
Alert.alert('알림', '다시 로그인 해주세요.');
}
} finally {
// TODO: 스플래시 스크린 없애기
SplashScreen.hide();
}
};
getTokenAndRefresh();
}, [dispatch]);
return (
<NavigationContainer>
{isLoggedIn ? (
<Tab.Navigator>
<Tab.Screen
name="Orders"
component={Orders}
options={{
title: '오더 목록',
tabBarIcon: () => <FontAwesome5 name="list" size={20} />,
}}
/>
<Tab.Screen
name="Delivery"
component={Delivery}
options={{
headerShown: false,
title: '지도',
tabBarIcon: () => <FontAwesome5 name="map" size={20} />,
// headerTitleStyle: {fontWeight: 'bold'},
// tabBarLabelStyle: {fontSize: 12},
}}
/>
<Tab.Screen
name="Settings"
component={Settings}
options={{
title: '내 정보',
tabBarIcon: () => <FontAwesome name="gear" size={20} />,
unmountOnBlur: true,
}}
/>
</Tab.Navigator>
) : (
<Stack.Navigator>
<Stack.Screen
name="SignIn"
component={SignIn}
options={{title: '로그인'}}
/>
<Stack.Screen
name="SignUp"
component={SignUp}
options={{title: '회원가입'}}
/>
</Stack.Navigator>
)}
</NavigationContainer>
);
}
export default AppInner;
아래는 백 서버 터미널 입니다 (이 부분이 계속 로딩됩니다)
C:\Users\user\fooddeliveryapp\back>npm start
> food-delivery-server@1.0.0 start
> node app.js
연결되었습니다.
TokenExpiredError: jwt expired
at C:\Users\user\fooddeliveryapp\back\node_modules\jsonwebtoken\verify.js:152:21
at getSecret (C:\Users\user\fooddeliveryapp\back\node_modules\jsonwebtoken\verify.js:90:14)
at module.exports [as verify] (C:\Users\user\fooddeliveryapp\back\node_modules\jsonwebtoken\verify.js:94:10)
at verifyRefreshToken (C:\Users\user\fooddeliveryapp\back\app.js:59:22)
at Layer.handle [as handle_request] (C:\Users\user\fooddeliveryapp\back\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\user\fooddeliveryapp\back\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\user\fooddeliveryapp\back\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\user\fooddeliveryapp\back\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\user\fooddeliveryapp\back\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\user\fooddeliveryapp\back\node_modules\express\lib\router\index.js:341:12) {
expiredAt: 2023-03-14T08:00:16.000Z
}
POST /refreshToken 419 91.985 ms - 70
잘 되다가 갑자기 이러니 당황스럽네요...ㅎㅎ
메트로 서버에서는 이렇게 나오네요
LOG Running "FoodDeliveryApp" with {"rootTag":11}
LOG !isLoggedIn true
LOG check location granted
백 서버를 껐다가 켠건데 왜 로그인이 되어있는 상태로 나올까요?
답변 1
1
refreshToken 자체가 만료돼서 그렇네요. await EncryptedStorage.clear() 한 번 제일 위에서 호출해서 jwt 지운 후에 다시 코드도 제거하세요.