Skip to content

Commit

Permalink
Merge pull request #44 from DearMyPeace/dev/app-login-logic/#43
Browse files Browse the repository at this point in the history
fix: app login logic/#43
  • Loading branch information
chanhihi authored Jul 2, 2024
2 parents 83b1160 + 7f7fc5f commit 7d298c5
Show file tree
Hide file tree
Showing 17 changed files with 318 additions and 234 deletions.
44 changes: 24 additions & 20 deletions ios/dearmypeace.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
5DF11AC526AA35A1BB355A2A /* libPods-dearmypeace.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1351DEF879BD1089EB9F682 /* libPods-dearmypeace.a */; };
5F2975D4800947B5B438A508 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A7D7DEC49252466C8666BA0C /* FontAwesome.ttf */; };
641965F627514DDBAF620056 /* Feather.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D5B1D94BBD1045779ABCC8F1 /* Feather.ttf */; };
64880C4F2C3283F9009E2304 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 64880C4E2C3283F8009E2304 /* GoogleService-Info.plist */; };
6C81110E134B4133B7BBFA58 /* AntDesign.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 391B37A4C9314BE58D0CA0BD /* AntDesign.ttf */; };
7C21F5F2D9E94F29BCDD103E /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A473DD0784EE4C70A9866D67 /* Ionicons.ttf */; };
7C48246F68C84F3CB383029D /* Foundation.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 76C538F261A64E7A9AFA721A /* Foundation.ttf */; };
Expand Down Expand Up @@ -65,6 +66,7 @@
39C746303B6C4263A279335D /* FontAwesome5_Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome5_Regular.ttf; path = ../src/assets/fonts/FontAwesome5_Regular.ttf; sourceTree = "<group>"; };
4AB4F72C4C2246A690E9A574 /* Fontisto.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Fontisto.ttf; path = ../src/assets/fonts/Fontisto.ttf; sourceTree = "<group>"; };
582A185F068242EA99AC1C92 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialCommunityIcons.ttf; path = ../src/assets/fonts/MaterialCommunityIcons.ttf; sourceTree = "<group>"; };
64880C4E2C3283F8009E2304 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../key/GoogleService-Info.plist"; sourceTree = "<group>"; };
64C8F1AC2C2BFBBD00CAC7F8 /* dearmypeace.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = dearmypeace.entitlements; path = dearmypeace/dearmypeace.entitlements; sourceTree = "<group>"; };
69C39DA37EE04490A92B2DD3 /* GowunBatang-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "GowunBatang-Regular.ttf"; path = "../src/assets/fonts/GowunBatang-Regular.ttf"; sourceTree = "<group>"; };
6DF4937B063240499BE351DD /* FontAwesome5_Brands.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome5_Brands.ttf; path = ../src/assets/fonts/FontAwesome5_Brands.ttf; sourceTree = "<group>"; };
Expand Down Expand Up @@ -133,6 +135,7 @@
13B07FAE1A68108700A75B9A /* dearmypeace */ = {
isa = PBXGroup;
children = (
64880C4E2C3283F8009E2304 /* GoogleService-Info.plist */,
64C8F1AC2C2BFBBD00CAC7F8 /* dearmypeace.entitlements */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.mm */,
Expand Down Expand Up @@ -239,8 +242,8 @@
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
625E41F738F2AF904F450BA5 /* [CP] Embed Pods Frameworks */,
BA0075308824C7B92195F1ED /* [CP] Copy Pods Resources */,
F894B917BE95BA54176F9201 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand All @@ -261,8 +264,8 @@
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
CED8580D144CD1D6A89F328E /* [CP] Embed Pods Frameworks */,
5B1D2728ADC6ABFF9B42A642 /* [CP] Copy Pods Resources */,
C96E59B62EB72AA922394C14 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -323,6 +326,7 @@
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
64880C4F2C3283F9009E2304 /* GoogleService-Info.plist in Resources */,
3503CAE617EAFAE94E7B529F /* PrivacyInfo.xcprivacy in Resources */,
FC7A548B569647A7B0A537E7 /* GowunBatang-Bold.ttf in Resources */,
37709B0C850C4E079916FAAF /* GowunBatang-Regular.ttf in Resources */,
Expand Down Expand Up @@ -384,23 +388,6 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-dearmypeace/Pods-dearmypeace-resources.sh\"\n";
showEnvVarsInLog = 0;
};
625E41F738F2AF904F450BA5 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-dearmypeace-dearmypeaceTests/Pods-dearmypeace-dearmypeaceTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-dearmypeace-dearmypeaceTests/Pods-dearmypeace-dearmypeaceTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-dearmypeace-dearmypeaceTests/Pods-dearmypeace-dearmypeaceTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
B6D01C1A1A561142C8718984 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -462,7 +449,7 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
CED8580D144CD1D6A89F328E /* [CP] Embed Pods Frameworks */ = {
C96E59B62EB72AA922394C14 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -479,6 +466,23 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-dearmypeace/Pods-dearmypeace-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
F894B917BE95BA54176F9201 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-dearmypeace-dearmypeaceTests/Pods-dearmypeace-dearmypeaceTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-dearmypeace-dearmypeaceTests/Pods-dearmypeace-dearmypeaceTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-dearmypeace-dearmypeaceTests/Pods-dearmypeace-dearmypeaceTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down
7 changes: 7 additions & 0 deletions ios/dearmypeace/AppDelegate.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <GoogleSignIn/GoogleSignIn.h>

@implementation AppDelegate

Expand Down Expand Up @@ -28,4 +29,10 @@ - (NSURL *)bundleURL
#endif
}

- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [GIDSignIn.sharedInstance handleURL:url];
}

@end
49 changes: 26 additions & 23 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import GoogleOAuthProviderWrapper from '@components/login/GoogleOAuthProviderWra
import MainNavigator from '@navigators/MainNavigator';
import SplashScreen from '@screens/common/SplashScreen';
import { lightTheme } from '@utils/lightTheme';
import BackgroundProvider from '@screens/common/BackgroundProvider';

const App = () => {
const [isLoading, setIsLoading] = useState(true);
Expand All @@ -29,29 +30,31 @@ const App = () => {

return (
<RecoilRoot>
<GoogleOAuthProviderWrapper>
<QueryClientProvider client={queryClient}>
<SafeAreaProvider>
<SafeAreaView style={styles.safeArea} edges={['bottom', 'left', 'right']}>
{isLoading ? (
<SplashScreen onFinish={() => setIsLoading(false)} />
) : (
<PaperProvider theme={theme}>
<NavigationContainer
theme={{
colors: {
background: 'transparent',
},
}}
>
<MainNavigator />
</NavigationContainer>
</PaperProvider>
)}
</SafeAreaView>
</SafeAreaProvider>
</QueryClientProvider>
</GoogleOAuthProviderWrapper>
<BackgroundProvider>
<GoogleOAuthProviderWrapper>
<QueryClientProvider client={queryClient}>
<SafeAreaProvider>
<SafeAreaView style={styles.safeArea} edges={['bottom', 'left', 'right']}>
{isLoading ? (
<SplashScreen onFinish={() => setIsLoading(false)} />
) : (
<PaperProvider theme={theme}>
<NavigationContainer
theme={{
colors: {
background: 'transparent',
},
}}
>
<MainNavigator />
</NavigationContainer>
</PaperProvider>
)}
</SafeAreaView>
</SafeAreaProvider>
</QueryClientProvider>
</GoogleOAuthProviderWrapper>
</BackgroundProvider>
</RecoilRoot>
);
};
Expand Down
35 changes: 34 additions & 1 deletion src/api/axios.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,42 @@
import axios from 'axios';
import { getToken } from '@components/login/AuthService';

const instance = axios.create({
baseURL: process.env.BASE_URL,
headers: { 'X-Custom-Header': 'foobar', 'Content-Type': 'application/json' },
timeout: 1000,
timeout: 10000,
});

instance.interceptors.request.use(
async (config) => {
console.log('Starting Request', JSON.stringify(config, null, 2));
if (config.url !== '/auth/google') {
const accessToken = await getToken();
if (accessToken) {
config.headers.Authorization = accessToken;
config.withCredentials = true;
}
}
return config;
},
(error) => {
return Promise.reject(error);
},
);

instance.interceptors.response.use(
(response) => {
console.log('Response:', JSON.stringify(response, null, 2));
return response;
},
(error) => {
console.log('Error Response:', JSON.stringify(error, null, 2));
if (error.message === 'Network Error' && error.config) {
error.config.__isRetryRequest = true;
return axios(error.config);
}
return Promise.reject(error);
},
);

export default instance;
23 changes: 22 additions & 1 deletion src/api/axios.web.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
import axios from 'axios';
import { getToken } from '@components/login/AuthService';

const instance = axios.create({
baseURL: process.env.BASE_URL,
headers: { 'X-Custom-Header': 'foobar', 'Content-Type': 'application/json' },
timeout: 1000,
});

instance.interceptors.request.use((request) => {
console.log('Starting Request', JSON.stringify(request, null, 2));
return request;
});

instance.interceptors.response.use(
(response) => {
console.log('Response:', JSON.stringify(response, null, 2));
return response;
},
(error) => {
console.log('Error Response:', JSON.stringify(error, null, 2));
if (error.message === 'Network Error' && error.config) {
error.config.__isRetryRequest = true;
return axios(error.config);
}
return Promise.reject(error);
},
);

instance.interceptors.request.use(
(config) => {
if (config.url === '/auth/google') {
return config;
}
// 로그인 후 토큰 헤더에 추가
const accessToken = localStorage.getItem('authToken');
const accessToken = getToken;
if (accessToken) {
config.headers.Authorization = accessToken;
config.withCredentials = true; // todo: 배포 시 삭제
Expand Down
Binary file added src/assets/images/background.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 18 additions & 49 deletions src/components/login/AuthService.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,29 @@
import { Platform } from 'react-native';
import EncryptedStorage from 'react-native-encrypted-storage';

const TOKEN_KEY = 'authToken';

const saveToken = async (token) => {
if (Platform.OS === 'web') {
try {
localStorage.setItem(TOKEN_KEY, token);
} catch (e) {
console.error('Failed to save token in web storage', e);
}
} else {
try {
const EncryptedStorage = (await import('react-native-encrypted-storage')).default;
await EncryptedStorage.setItem(TOKEN_KEY, token);
} catch (e) {
console.error('Failed to save token in encrypted storage', e);
}
export const saveToken = async (token: string) => {
try {
await EncryptedStorage.setItem(TOKEN_KEY, token);
} catch (e) {
console.error('Failed to save token in encrypted storage', e);
}
};

const getToken = async () => {
if (Platform.OS === 'web') {
try {
const token = localStorage.getItem(TOKEN_KEY);
return token;
} catch (e) {
console.error('Failed to load token from web storage', e);
return null;
}
} else {
try {
const EncryptedStorage = (await import('react-native-encrypted-storage')).default;
const token = await EncryptedStorage.getItem(TOKEN_KEY);
return token;
} catch (e) {
console.error('Failed to load token from encrypted storage', e);
return null;
}
export const getToken = async () => {
try {
const token = await EncryptedStorage.getItem(TOKEN_KEY);
return token;
} catch (e) {
console.error('Failed to load token from encrypted storage', e);
return null;
}
};

const removeToken = async () => {
if (Platform.OS === 'web') {
try {
localStorage.removeItem(TOKEN_KEY);
} catch (e) {
console.error('Failed to remove token from web storage', e);
}
} else {
try {
const EncryptedStorage = (await import('react-native-encrypted-storage')).default;
await EncryptedStorage.removeItem(TOKEN_KEY);
} catch (e) {
console.error('Failed to remove token from encrypted storage', e);
}
export const removeToken = async () => {
try {
await EncryptedStorage.removeItem(TOKEN_KEY);
} catch (e) {
console.error('Failed to remove token from encrypted storage', e);
}
};

export { saveToken, getToken, removeToken };
27 changes: 27 additions & 0 deletions src/components/login/AuthService.web.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const TOKEN_KEY = 'authToken';

export const saveToken = async (token: string) => {
try {
localStorage.setItem(TOKEN_KEY, token);
} catch (e) {
console.error('Failed to save token in web storage', e);
}
};

export const getToken = async () => {
try {
const token = localStorage.getItem(TOKEN_KEY);
return token;
} catch (e) {
console.error('Failed to load token from web storage', e);
return null;
}
};

export const removeToken = async () => {
try {
localStorage.removeItem(TOKEN_KEY);
} catch (e) {
console.error('Failed to remove token from web storage', e);
}
};
2 changes: 1 addition & 1 deletion src/hooks/login/logoutHook.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useResetRecoilState, useSetRecoilState } from 'recoil';
import { authTokenState, isLoggedInState, userInfoState } from '@stores/login.ts';
import { removeToken } from '@components/login/AuthService.ts';
import { removeToken } from '@components/login/AuthService';
import { useMutation } from '@tanstack/react-query';
import { logoutRequest, deleteAccountRequest } from '@api/auth/delete';
import { snackMessage } from '@stores/snackMessage';
Expand Down
Loading

0 comments on commit 7d298c5

Please sign in to comment.