Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import axios, { AxiosResponse } from 'axios';
import { getStorage } from '~/assets/util/storage';
import { TOKEN_STORAGE_KEY } from '~/assets/util/constants';
import { CustomResponse } from 'types/modules';
import { TokenObservers } from '~/observers/token';

//
if (__DEV__) {
Expand Down Expand Up @@ -68,6 +69,7 @@ export default function App() {
<RecoilRoot>
<NavigationContainer ref={navigationRef}>
<RootNavigator />
<TokenObservers />
<AppStateComponent />
<SimpleSnackbarUI.Portal />
</NavigationContainer>
Expand Down
30 changes: 30 additions & 0 deletions app/api/login.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import axios from 'axios';
import { Envelope, SocialLoginRoute } from 'types/common';
import { REFRESH_TOKEN_KEY } from '~/assets/util/constants';
import { getStorage } from '~/assets/util/storage';

interface TokenParams {
id_token: string;
Expand All @@ -21,3 +23,31 @@ export const postLogin = async (
// TODO: 사실 이 부분은 api가 통합되어야 할 듯 => 수정될 것 같음
return axios.post(`/login/${route}`, params);
};

// WIP 에러코드랑 토큰 보내느 형식 다시 맞춰야할듯
let cached = null;
let lastCall = 0;
const maxAge = 1000; // 캐시 유지 기간 (밀리초)

export const refreshTokenAPI = async () => {
const now = Date.now();

if (cached !== null && now - lastCall < maxAge) {
return cached; // 캐시된 결과 반환
}

lastCall = now; // 호출 시간 업데이트

try {
const response = await axios.post(`/user/reToken`, {
refresh: await getStorage(REFRESH_TOKEN_KEY),
});
cached = response.data; // 응답 캐시
return cached;
} catch (error) {
cached = null; // 오류 발생 시 캐시 초기화
// 리프레시 토큰 만료 처리 로직

// 리프레시 토큰도 만료됨으로써 로그인페이지로 리다이렉트 처리해야함
}
};
1 change: 1 addition & 0 deletions app/api/user.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios from 'axios';

export const getUserInfoAPI = async () => {
console.log('## 동작?');
return await axios.get('/user');
};
1 change: 1 addition & 0 deletions app/assets/util/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export const sortOptions: SortType[] = [
];

export const TOKEN_STORAGE_KEY = 'NT-AUTH-TOKEN';
export const REFRESH_TOKEN_KEY = 'NT-REFRESH-TOKEN';
1 change: 0 additions & 1 deletion app/hooks/map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export function useMapTrade() {
defaultCenterPosition || userPosition,
);

console.log('@@@@@@@@@@@Zoom', centerMapInfo);
const [mapCenter, setMapCenter] = useState(
defaultCenterPosition || userPosition,
);
Expand Down
5 changes: 4 additions & 1 deletion app/hooks/user/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { getUserInfoAPI } from 'api/user';
import { useQuery } from '@tanstack/react-query';
import { userKeys } from '../../key/user';

export function useUser() {
export function useUser(token: string) {
console.log('@@ token', token);

const userInfo = useQuery({
queryKey: userKeys.info(),
queryFn: getUserInfoAPI,
enabled: !!token,
});

return userInfo;
Expand Down
8 changes: 5 additions & 3 deletions app/observers/app-state.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useEffect, useRef } from 'react';
import { AppState } from 'react-native';
import { useSetRecoilState } from 'recoil';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { userAppState } from '~/state/app';

export const AppStateComponent = () => {
const appState = useRef(AppState.currentState);
const setUserAppState = useSetRecoilState(userAppState);
console.log('@ 현재 상태 appState:', appState);
const State = useRecoilValue(userAppState);

console.log('@ 현재 상태 appState:', State);

useEffect(() => {
// 사용자가 앱의 상태가 변경 되었을 경우 실행이 된다.
Expand All @@ -25,7 +27,7 @@ export const AppStateComponent = () => {
}, []);

const handleAppState = (nextAppState: any) => {
// console.log('@ appState.current ::: ', appState.current);
console.log('@ appState.current ::: ', appState.current);

// 앱 활성화
if (
Expand Down
24 changes: 24 additions & 0 deletions app/observers/token.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import { TOKEN_STORAGE_KEY } from '~/assets/util/constants';
import { getStorage } from '~/assets/util/storage';
import { userAppState } from '~/state/app';
import { navigationRef } from '~/../RootNavigation';
import { refreshTokenAPI } from '~/api/login';

export const TokenObservers = () => {
const appState = useRecoilValue(userAppState);

useEffect(() => {
// 이미 로그인 했을 때(토큰이 저장되어 있을 때)
getStorage(TOKEN_STORAGE_KEY).then((data) => {
if (data && appState == 'active') {
console.log('@@ TokenObservers', data);
// navigationRef.current.navigate('MainScreen');
}
});
}, [appState]);

return null;
};
16 changes: 13 additions & 3 deletions app/screens/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { SocialLoginRoute } from 'types/common';
import { useUser } from 'hooks/user';
import { RootStackParamList } from './stack';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { useFocusEffect } from '@react-navigation/native';

const naverLoginKeys = {
consumerKey: 'vnH89uX9Nczv8vOeXfQw', // 이거 필요한건가?
Expand Down Expand Up @@ -86,24 +87,25 @@ type Props = NativeStackScreenProps<RootStackParamList, 'RootScreen'>;

const RootScreen = ({ navigation }: Props) => {
const [serviceToken, setSeviceToken] = useState<string>(); // 우리 서버에서 로그인 되고 나면 저장하려고 했음
const userInfo = useUser();
const userInfo = useUser(serviceToken);

console.log('@@@ userInfo', userInfo.data);
const setToken = (token?: string) => {
if (!token) return;
setSeviceToken(token);
setStorage(TOKEN_STORAGE_KEY, token);
console.log('@@ 토큰 저장 잘 하나', token, serviceToken);
};

useEffect(() => {
if (!serviceToken) {
getStorage(TOKEN_STORAGE_KEY).then((data) => {
console.log('@@ user', data);

if (!data) return;
setSeviceToken(data);
});
return;
}
console.log('user', userInfo);
// 1. serviceToken으로 user 정보 불러옴 (react query)
// 2-1. 선택한 학교가 없으면 학교 선택 페이지로 이동
// navigation.navigate('UniversityScreen');
Expand Down Expand Up @@ -142,6 +144,14 @@ const RootScreen = ({ navigation }: Props) => {
<Pressable onPress={() => navigation.navigate('MainScreen')}>
<LaterLogin>나중에 로그인하기</LaterLogin>
</Pressable>
<Pressable
onPress={() => {
console.log('@@ 토큰저장');
setStorage(TOKEN_STORAGE_KEY, 'TEST');
}}
>
<LaterLogin>토큰 설정하기</LaterLogin>
</Pressable>
</SocialLoginWrap>
</Container>
</SafeAreaView>
Expand Down
2 changes: 1 addition & 1 deletion axiosConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const AxiosConfig = () => {
);

axios.interceptors.response.use((response: AxiosResponse<CustomResponse>) => {
console.log('@@ AXIOS RESPONSE 123', response);
// console.log('@@ AXIOS RESPONSE 123', response);
return response.data.data;
});

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@
"axios": "^1.5.0",
"babel-plugin-module-resolver": "^5.0.0",
"jwt-decode": "^4.0.0",
"mem": "^10.0.0",
"memoize": "^10.0.0",
"moment": "^2.29.4",
"p-memoize": "^7.1.1",
"patch-package": "^7.0.0",
"postinstall-postinstall": "^2.1.0",
"react": "18.2.0",
Expand Down
50 changes: 50 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10295,6 +10295,13 @@ makeerror@1.0.12:
dependencies:
tmpl "1.0.5"

map-age-cleaner@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
dependencies:
p-defer "^1.0.0"

map-cache@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
Expand Down Expand Up @@ -10389,6 +10396,14 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==

mem@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/mem/-/mem-10.0.0.tgz#08348356ec2c62148d788f07f2e781dea68524cd"
integrity sha512-ucHuGY0h9IKre1NAf8iRyBQhlmuISr0zEOHuLc7szfkUWiaVzuG1g7piPkVl4rVj362pjxsqiOANtDdI7mv86A==
dependencies:
map-age-cleaner "^0.1.3"
mimic-fn "^4.0.0"

memfs@^3.1.2:
version "3.6.0"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6"
Expand All @@ -10406,6 +10421,13 @@ memoize-one@^6.0.0:
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==

memoize@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/memoize/-/memoize-10.0.0.tgz#43fa66b2022363c7c50cf5dfab732a808a3d7147"
integrity sha512-H6cBLgsi6vMWOcCpvVCdFFnl3kerEXbrYh9q+lY6VXvQSmM6CkmV08VOwT+WE2tzIEqRPFfAq3fm4v/UIW6mSA==
dependencies:
mimic-function "^5.0.0"

memoizerific@^1.11.3:
version "1.11.3"
resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a"
Expand Down Expand Up @@ -10968,6 +10990,16 @@ mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==

mimic-fn@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc"
integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==

mimic-function@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076"
integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==

mimic-response@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
Expand Down Expand Up @@ -11631,6 +11663,11 @@ p-cancelable@^2.0.0:
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==

p-defer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==

p-event@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5"
Expand Down Expand Up @@ -11704,6 +11741,14 @@ p-map@^4.0.0:
dependencies:
aggregate-error "^3.0.0"

p-memoize@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/p-memoize/-/p-memoize-7.1.1.tgz#53b1d0e6007288f7261cfa11a7603b84c9261bfa"
integrity sha512-DZ/bONJILHkQ721hSr/E9wMz5Am/OTJ9P6LhLFo2Tu+jL8044tgc9LwHO8g4PiaYePnlVVRAJcKmgy8J9MVFrA==
dependencies:
mimic-fn "^4.0.0"
type-fest "^3.0.0"

p-timeout@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe"
Expand Down Expand Up @@ -14620,6 +14665,11 @@ type-fest@^0.8.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==

type-fest@^3.0.0:
version "3.13.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706"
integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==

type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
Expand Down