Skip to content

Commit

Permalink
[4/12] Kan 22 Connect API (login, signup, autoLogin) (#6)
Browse files Browse the repository at this point in the history
* Feat/APIconnect

* Feat/Auto Login with token

* Add/annotation
  • Loading branch information
sjsjmine129 authored Apr 12, 2024
1 parent 48d6eff commit 18eab8f
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 64 deletions.
29 changes: 24 additions & 5 deletions src/screens/home/HomeScreen.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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 (
<>
Expand All @@ -31,11 +51,10 @@ export default function HomeScreen() {
</AnimatedButton>
<AnimatedButton
onPress={() => {
console.log('PRESSED~!!');
navigation.navigate('ListNavigator');
helloAPI();
}}
style={styles.buttonTest}>
<Text style={styles.buttonText}>ListNavigator</Text>
<Text style={styles.buttonText}>Hello API Check</Text>
</AnimatedButton>
</View>
</>
Expand Down
58 changes: 35 additions & 23 deletions src/screens/signup/LoginScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,25 @@ 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();

//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);
Expand All @@ -52,38 +59,43 @@ export default function LoginScreen() {
}
}, [email, password]);

// 이메일 입력이 끝나면 패스워드 입력으로 커서를 이동시키는 함수
const endEmailInput = () => {
passwordInputRef.current.focus();
};

// 로그인 하는 함수 -> 버튼 누르면 & 입력하고 엔터 누르면 작동
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);

// 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-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);

navigation.navigate('BottomTab');
} catch (error) {
Expand Down
44 changes: 21 additions & 23 deletions src/screens/signup/SignupScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -160,7 +156,9 @@ export default function SignupScreen() {
</AnimatedButton>
<TextInput
ref={passwordInputRef}
onSubmitEditing={signUp}
onSubmitEditing={async () => {
await signUp();
}}
secureTextEntry={passwordShow}
autoCapitalize="none"
placeholderTextColor={COLOR_GRAY}
Expand Down
33 changes: 20 additions & 13 deletions src/screens/signup/SplashScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,52 @@ export default function SplashScreen() {
const navigation = useNavigation();
const context = useContext(AppContext);

//TODO: 저장된 토큰 가져와서 로그인 시도해보는 로직
const tryAutoLogin = async () => {
try {
// AsyncStorage(=디바이스에 저장하는 데이터)에 저장된 토큰을 가져온다.
const accessToken = await AsyncStorage.getItem('accessToken');
const refreshToken = await AsyncStorage.getItem('refreshToken');

if (accessToken == null || refreshToken == null) {
//없으면 그만
console.log('accessToken:', accessToken);
if (accessToken == 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`, {
headers: {Authorization: `Bearer ${accessToken}`},
});
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에 저장하고 화면 이동
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 (
<View style={styles.entire}>
<Text style={styles.textMain}>먹구스꾸</Text>
Expand Down

0 comments on commit 18eab8f

Please sign in to comment.