From c03e23c045d109518e6e857d2e6f9a486e8c0b83 Mon Sep 17 00:00:00 2001 From: sjsjmine129 Date: Fri, 12 Apr 2024 10:13:56 +0900 Subject: [PATCH 1/3] Feat/APIconnect --- src/screens/signup/LoginScreen.js | 36 +++++++++++------------- src/screens/signup/SignupScreen.js | 44 ++++++++++++++---------------- src/screens/signup/SplashScreen.js | 16 +++++------ 3 files changed, 44 insertions(+), 52 deletions(-) diff --git a/src/screens/signup/LoginScreen.js b/src/screens/signup/LoginScreen.js index e87b322..f6d496b 100644 --- a/src/screens/signup/LoginScreen.js +++ b/src/screens/signup/LoginScreen.js @@ -32,6 +32,7 @@ import {SvgXml} from 'react-native-svg'; import {svgXml} from '../../assets/svg'; import LongPrimaryButton from '../../components/LongPrimaryButton'; import AppContext from '../../components/AppContext'; +import AsyncStorage from '@react-native-async-storage/async-storage'; export default function LoginScreen() { const navigation = useNavigation(); @@ -57,33 +58,28 @@ export default function LoginScreen() { }; const login = async () => { - //TODO: 로그인 API 호출 & 토큰 저장 console.log('email:', email); console.log('password:', password); try { - //TODO: 로그인 API확인 //로그인 하고 토큰 저장하는 부분 - // const response = await axios.post( - // `${API_URL}/v1/users/email/sign-in`, - // { - // email: email, - // password: password, - // }, - // ); - // console.log('response:', response.data.data); + const response = await axios.post(`${API_URL}/v1/users/email/sign-in`, { + email: email, + password: password, + }); + console.log('response:', response.data.data); - // if (!response.data.data) { - // console.log('Error: No return data'); - // return; - // } - // const accessToken = response.data.data.accessToken; - // const refreshToken = response.data.data.refreshToken; + if (!response.data.data) { + console.log('Error: No return data'); + return; + } + const accessToken = response.data.data.token.accessToken; + const refreshToken = response.data.data.token.refreshToken; - // context.setAccessTokenValue(accessToken); - // context.setRefreshTokenValue(refreshToken); - // AsyncStorage.setItem('accessToken', accessToken); - // AsyncStorage.setItem('refreshToken', refreshToken); + context.setAccessTokenValue(accessToken); + context.setRefreshTokenValue(refreshToken); + AsyncStorage.setItem('accessToken', accessToken); + AsyncStorage.setItem('refreshToken', refreshToken); navigation.navigate('BottomTab'); } catch (error) { diff --git a/src/screens/signup/SignupScreen.js b/src/screens/signup/SignupScreen.js index c28c41d..80927f2 100644 --- a/src/screens/signup/SignupScreen.js +++ b/src/screens/signup/SignupScreen.js @@ -70,29 +70,25 @@ export default function SignupScreen() { console.log('password:', password); try { - //TODO: 회원가입 API확인 //회원가입 하고 토큰 저장하는 부분 - // const response = await axios.post( - // `${API_URL}​/v1​/users​/email​/sign-up`, - // { - // email: email, - // nickname: name, - // password: password, - // }, - // ); - // console.log('response:', response.data.data); - - // if (!response.data.data) { - // console.log('Error: No return data'); - // return; - // } - // const accessToken = response.data.data.accessToken; - // const refreshToken = response.data.data.refreshToken; - - // context.setAccessTokenValue(accessToken); - // context.setRefreshTokenValue(refreshToken); - // AsyncStorage.setItem('accessToken', accessToken); - // AsyncStorage.setItem('refreshToken', refreshToken); + const response = await axios.post(`${API_URL}/v1/users/email/sign-up`, { + email: email, + nickname: name, + password: password, + }); + console.log('response:', response.data.data); + + if (!response.data.data) { + console.log('Error: No return data'); + return; + } + const accessToken = response.data.data.token.accessToken; + const refreshToken = response.data.data.token.refreshToken; + + context.setAccessTokenValue(accessToken); + context.setRefreshTokenValue(refreshToken); + AsyncStorage.setItem('accessToken', accessToken); + AsyncStorage.setItem('refreshToken', refreshToken); navigation.navigate('BottomTab'); } catch (error) { @@ -160,7 +156,9 @@ export default function SignupScreen() { { + await signUp(); + }} secureTextEntry={passwordShow} autoCapitalize="none" placeholderTextColor={COLOR_GRAY} diff --git a/src/screens/signup/SplashScreen.js b/src/screens/signup/SplashScreen.js index bf022b5..0773ff5 100644 --- a/src/screens/signup/SplashScreen.js +++ b/src/screens/signup/SplashScreen.js @@ -19,27 +19,25 @@ export default function SplashScreen() { const navigation = useNavigation(); const context = useContext(AppContext); - //TODO: 저장된 토큰 가져와서 로그인 시도해보는 로직 const tryAutoLogin = async () => { try { const accessToken = await AsyncStorage.getItem('accessToken'); const refreshToken = await AsyncStorage.getItem('refreshToken'); + console.log('accessToken:', accessToken); if (accessToken == null || refreshToken == null) { return; } //TODO: 토큰 로그인 API확인 //토큰으로 로그인 하는 부분 - // const response = await axios.get( - // `${API_URL}/hello/security-test` - // ); - // console.log('response:', response.data.data); + const response = await axios.get(`${API_URL}/hello/security-test`); + console.log('response:', response.data.data); - // if (!response.data.data) { - // console.log('Error: No return data'); - // return; - // } + if (!response.data.data) { + console.log('Error: No return data'); + return; + } context.setAccessTokenValue(accessToken); context.setRefreshTokenValue(refreshToken); From b783fdbcf9189cfd03cd5ca8cda4e41721f7251b Mon Sep 17 00:00:00 2001 From: sjsjmine129 Date: Fri, 12 Apr 2024 19:18:15 +0900 Subject: [PATCH 2/3] Feat/Auto Login with token --- src/screens/home/HomeScreen.js | 29 ++++++++++++++++++++++++----- src/screens/signup/SplashScreen.js | 9 +++++---- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/screens/home/HomeScreen.js b/src/screens/home/HomeScreen.js index 0b4efc9..8328a5a 100644 --- a/src/screens/home/HomeScreen.js +++ b/src/screens/home/HomeScreen.js @@ -1,4 +1,4 @@ -import React, {useState, useCallback, useEffect} from 'react'; +import React, {useState, useCallback, useEffect, useContext} from 'react'; import {View, Text, SafeAreaView, ScrollView, StyleSheet} from 'react-native'; import { COLOR_WHITE, @@ -11,10 +11,30 @@ import {useNavigation} from '@react-navigation/native'; import {SvgXml} from 'react-native-svg'; import {svgXml} from '../../assets/svg'; import Header from '../../components/Header'; - +import AppContext from '../../components/AppContext'; +import axios from 'axios'; +import {API_URL} from '@env'; export default function HomeScreen() { const navigation = useNavigation(); + const context = useContext(AppContext); + + const helloAPI = async () => { + try { + const response = await axios.get(`${API_URL}/hello/security-test`, { + headers: {Authorization: `Bearer ${context.accessToken}`}, + }); + + console.log('response:', response.data.data); + + if (!response.data.data) { + console.log('Error: No return data'); + return; + } + } catch (e) { + console.log('error', e); + } + }; return ( <> @@ -31,11 +51,10 @@ export default function HomeScreen() { { - console.log('PRESSED~!!'); - navigation.navigate('ListNavigator'); + helloAPI(); }} style={styles.buttonTest}> - ListNavigator + Hello API Check diff --git a/src/screens/signup/SplashScreen.js b/src/screens/signup/SplashScreen.js index 0773ff5..0e8b235 100644 --- a/src/screens/signup/SplashScreen.js +++ b/src/screens/signup/SplashScreen.js @@ -25,13 +25,13 @@ export default function SplashScreen() { const refreshToken = await AsyncStorage.getItem('refreshToken'); console.log('accessToken:', accessToken); - if (accessToken == null || refreshToken == null) { + if (accessToken == null) { return; } - - //TODO: 토큰 로그인 API확인 //토큰으로 로그인 하는 부분 - const response = await axios.get(`${API_URL}/hello/security-test`); + const response = await axios.get(`${API_URL}/hello/security-test`, { + headers: {Authorization: `Bearer ${accessToken}`}, + }); console.log('response:', response.data.data); if (!response.data.data) { @@ -41,6 +41,7 @@ export default function SplashScreen() { context.setAccessTokenValue(accessToken); context.setRefreshTokenValue(refreshToken); + navigation.navigate('BottomTab'); } catch (e) { console.log('error', e); From d4a739dd50f90564f061bd7144b2c2fd5e72fc1f Mon Sep 17 00:00:00 2001 From: sjsjmine129 Date: Fri, 12 Apr 2024 19:39:12 +0900 Subject: [PATCH 3/3] Add/annotation --- src/screens/signup/LoginScreen.js | 18 +++++++++++++++++- src/screens/signup/SplashScreen.js | 12 ++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/screens/signup/LoginScreen.js b/src/screens/signup/LoginScreen.js index f6d496b..7acfb9b 100644 --- a/src/screens/signup/LoginScreen.js +++ b/src/screens/signup/LoginScreen.js @@ -36,15 +36,21 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; export default function LoginScreen() { const navigation = useNavigation(); + + //state 선언 -> UI에 영향을 미치는 변수들 만약 이게 바뀌었을때 화면이 바뀌어야하면 state로 선언 const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [passwordShow, setPasswordShow] = useState(true); const [disable, setDisable] = useState(true); + //ref 선언 -> 요소를 직접 제어할때 사용 const emailInputRef = useRef(null); const passwordInputRef = useRef(null); + + // 앱내부에서 전역변수로 사용하는 것 쓰고싶으면 선언한다 const context = useContext(AppContext); + // [ ] 안의 State가 변경될 때마다 실행된다. 여기서는 email, password가 변경될 때마다 실행되서 로그인 버튼이 활성화 될지 비활성화 될지 결정한다. useEffect(() => { if (email && password && disable) { setDisable(false); @@ -53,31 +59,41 @@ export default function LoginScreen() { } }, [email, password]); + // 이메일 입력이 끝나면 패스워드 입력으로 커서를 이동시키는 함수 const endEmailInput = () => { passwordInputRef.current.focus(); }; + // 로그인 하는 함수 -> 버튼 누르면 & 입력하고 엔터 누르면 작동 const login = async () => { console.log('email:', email); console.log('password:', password); try { - //로그인 하고 토큰 저장하는 부분 + // 백엔드 요청 -> 아직 로그인 전인 백엔드 요청이라 토큰이 필요없다. const response = await axios.post(`${API_URL}/v1/users/email/sign-in`, { email: email, password: password, }); + + //출력 console.log('response:', response.data.data); + //백엔드에서 받은 데이터가 없으면 에러 출력 if (!response.data.data) { console.log('Error: No return data'); return; } + + //백엔드에서 받은 토큰을 저장하고 화면 이동 const accessToken = response.data.data.token.accessToken; const refreshToken = response.data.data.token.refreshToken; + //전역 변수에 저장 context.setAccessTokenValue(accessToken); context.setRefreshTokenValue(refreshToken); + + //디바이스에 저장 AsyncStorage.setItem('accessToken', accessToken); AsyncStorage.setItem('refreshToken', refreshToken); diff --git a/src/screens/signup/SplashScreen.js b/src/screens/signup/SplashScreen.js index 0e8b235..3c022d4 100644 --- a/src/screens/signup/SplashScreen.js +++ b/src/screens/signup/SplashScreen.js @@ -21,42 +21,50 @@ export default function SplashScreen() { const tryAutoLogin = async () => { try { + // AsyncStorage(=디바이스에 저장하는 데이터)에 저장된 토큰을 가져온다. const accessToken = await AsyncStorage.getItem('accessToken'); const refreshToken = await AsyncStorage.getItem('refreshToken'); + //없으면 그만 console.log('accessToken:', accessToken); if (accessToken == null) { return; } - //토큰으로 로그인 하는 부분 + + //토큰이 맞는지 확인 -> 헤더에 토큰 넣어서 백엔드 요청 const response = await axios.get(`${API_URL}/hello/security-test`, { headers: {Authorization: `Bearer ${accessToken}`}, }); console.log('response:', response.data.data); + //토큰이 맞지 않으면 그만 if (!response.data.data) { console.log('Error: No return data'); return; } + //토큰이 맞으면 context에 저장하고 화면 이동 context.setAccessTokenValue(accessToken); context.setRefreshTokenValue(refreshToken); + //화면 이동 navigation.navigate('BottomTab'); } catch (e) { console.log('error', e); } }; - // run at first time + // [] 에 state를 넣으면 state가 변경될 때마다 실행된다. 근데 아무것도 없으면 처음 로딩될때만 작동 = 초기화용 useEffect(() => { tryAutoLogin(); }, []); + //버튼 눌렀을 때의 작동함수 const pressButton = async () => { navigation.navigate('Login'); }; + //이 함수형 컴포넌트가 화면에 보여지는 부분 return ( 먹구스꾸