Skip to content

Commit

Permalink
Merge pull request #47 from BOBpossible/feat/#10_LoginAPI
Browse files Browse the repository at this point in the history
Feat/#10 login api
  • Loading branch information
psh320 authored Jul 8, 2022
2 parents 122f908 + ab36152 commit 17629eb
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 127 deletions.
22 changes: 8 additions & 14 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {enableScreens} from 'react-native-screens';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {QueryClient, QueryClientProvider} from 'react-query';
import {customAxios} from './src/api/customAxios';
import {getRegisterStatus, postToken} from './src/api';

enableScreens();

Expand All @@ -30,25 +31,18 @@ export default function App() {
return () => clearTimeout(id);
}, []);

const getRegisterStatus = async (token: string) => {
try {
//진범이가 실제 get api 만들어주면 정확한 url 입력 요망
const response = await customAxios(token).get('/v1/api/user/registerStatus');
if (response.data.result.registerStatus === 'DONE') {
setIsLogin(true);
}
} catch (error) {
console.log('register Status', error);
}
};

const getToken = async () => {
try {
const value = await AsyncStorage.getItem('userToken');
const value = await AsyncStorage.getItem('accessToken');
//여기서 아이디는 있지만 회원가입을 다 안한 상태라면 로그인 창 띄우고 했다면 메인으로 바로 가기.
if (value !== null) {
//GET user register status 그리고 그안에서 setIslogin true 만들거나 false로 냅두기
getRegisterStatus(value);

await postToken();
const registerResult = await getRegisterStatus();
if (registerResult === 'DONE') {
setIsLogin(true);
}
}
} catch (e) {
console.log(e);
Expand Down
89 changes: 76 additions & 13 deletions src/api/customAxios.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,80 @@
import axios, {AxiosInstance} from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const customAxios = (token?: string, params?: {}): AxiosInstance => {
console.log(params);
if (token === undefined) {
return axios.create({
baseURL: 'https://bobpossible.shop',
});
} else {
return axios.create({
baseURL: 'https://bobpossible.shop',
headers: {
Authorization: `Bearer ${token}`,
},
});
const getAccessToken = async () => {
try {
const value = await AsyncStorage.getItem('accessToken');
if (value !== null) {
return value;
}
} catch (e) {
console.log(e);
}
};

const getRefreshToken = async () => {
try {
const value = await AsyncStorage.getItem('refreshToken');
if (value !== null) {
console.log(value);
return value;
}
} catch (e) {
console.log(e);
}
};

export const customAxios = (): AxiosInstance => {
const axiosInstance = axios.create({
baseURL: 'https://bobpossible.shop',
});

axiosInstance.interceptors.request.use(
async (config: any) => {
const token = await getAccessToken();
config.headers.Authorization = `Bearer ${token}`;
return config;
},
function (error) {
// Do something with request error
// 요청 시 에러 처리
return Promise.reject(error);
},
);

axiosInstance.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const {
config,
response: {status},
} = error;
if (status === 401) {
const accessToken = await getAccessToken();
const refreshToken = await getRefreshToken();
const originalRequest = config;
// token refresh 요청
const {data} = await axios.post(
'https://bobpossible.shop/auth/token', // token refresh api
null,
{params: {accessToken: accessToken, refreshToken: refreshToken}},
);
// 새로운 토큰 저장
console.log('토큰이 만료 되어 토큰 갱신한 데이터: ', data);
const {accessToken: newAccessToken, refreshToken: newRefreshToken} = data;
await AsyncStorage.multiSet([
['accessToken', newAccessToken],
['refreshToken', newRefreshToken],
]);
axios.defaults.headers.common.Authorization = `Bearer ${newAccessToken}`;
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
// 401로 요청 실패했던 요청 새로운 accessToken으로 재요청
return axios(originalRequest);
}
return Promise.reject(error);
},
);
return axiosInstance;
};
3 changes: 3 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './customAxios';
export * from './login';
export * from './kakaoGeocoder';
43 changes: 43 additions & 0 deletions src/api/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {customAxios} from './customAxios';
import AsyncStorage from '@react-native-async-storage/async-storage';

const getAccessToken = async () => {
const accesstoken = await AsyncStorage.getItem('accessToken');
return accesstoken;
};

const getRefreshToken = async () => {
const refreshtoken = await AsyncStorage.getItem('accessToken');
return refreshtoken;
};

export const postToken = async () => {
const accessToken = await getAccessToken();
const refreshToken = await getRefreshToken();
console.log('엑세스 토큰: ', accessToken);
console.log('리프레시 토큰: ', refreshToken);
try {
const response = await customAxios().post('/auth/token', null, {
params: {accessToken: accessToken, refreshToken: refreshToken},
});
console.log('리프레시 토큰 응답: ', response);
await AsyncStorage.multiSet([
['accessToken', response.data.result.accessToken],
['refreshToken', response.data.result.refreshToken],
]);
console.log('리프레시 토큰 성공: ', response);
return response;
} catch (error) {
console.log('토큰 리프레시 갱신 에러: ', error);
}
};

//유저가 앱을 킬때 스플래시화면에서 token이 asyncStorage에 있다면 회원가입 완료 인지 아닌지 확인 해주는 api
export const getRegisterStatus = async () => {
try {
const response = await customAxios().get('/api/v1/users/me/register-status');
return response.data.result.registerStatus;
} catch (error) {
console.log('register Status', error);
}
};
28 changes: 28 additions & 0 deletions src/components/ConnectionError.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, {FC} from 'react';
import {Image, Text, TouchableOpacity, View} from 'react-native';
import {DesignSystem} from '../assets/DesignSystem';

export type ConnectionErrorProps = {
refetch: any;
};

export const ConnectionError: FC<ConnectionErrorProps> = ({refetch}) => {
return (
<View style={[DesignSystem.centerArrange, {flex: 1, marginBottom: 50}]}>
<Image source={require('../assets/images/noMission/cryingBob.png')} />
<Text style={[DesignSystem.title1SB, {color: '#111111', marginBottom: 2}]}>
연결에 실패했어요
</Text>
<Text style={[DesignSystem.body1Lt, {color: '#94949', marginBottom: 38}]}>
네트워크를 확인해주세요
</Text>
<TouchableOpacity
onPress={() => {
refetch();
}}
>
<Text>새로고침</Text>
</TouchableOpacity>
</View>
);
};
18 changes: 11 additions & 7 deletions src/components/Home/HomeAnimatedHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,31 @@ import {customAxios} from '../../api/customAxios';
import {useRecoilValue} from 'recoil';
import {userToken} from '../../state';
import {HomeData} from '../../screens/Home/Main';
import AsyncStorage from '@react-native-async-storage/async-storage';

const WIDTH = Dimensions.get('window').width;
const HEADER_HEIGHT = Platform.OS === 'ios' ? hp(25.8) : hp(28.6);
type AnimatedHeaderProps = {
animatedValue: Animated.Value;
paddingTop: number;
data?: HomeData;
};

export const AnimatedHeader: FC<AnimatedHeaderProps> = ({animatedValue, paddingTop}) => {
export const AnimatedHeader: FC<AnimatedHeaderProps> = ({animatedValue, paddingTop, data}) => {
const [addressModal, setAddressModal] = useState(false);
const barProgressValue = useRef(new Animated.Value(0)).current;
const navigation = useNavigation();
const token = useRecoilValue(userToken);
const token = AsyncStorage.getItem('accessToken');

//주소동 받는 퀘리 있어야함

const getHomeInfo = async () => {
const response = await customAxios(token).get('/api/v1/missions/me');
return response.data.result;
};
const {data} = useQuery<HomeData>('homeInfo', getHomeInfo);
// const getHomeInfo = async () => {
// const response = await customAxios(await token).get('/api/v1/missions/me');
// return response.data.result;
// };
// const {data} = useQuery<HomeData>('homeInfo', getHomeInfo, {
// retry: false,
// });

//헤더 길이 바꿔주는 애니메이션 Main.tsx의 스크롤 위치에 따라 변한다
const heightAnimStyle = useStyle({
Expand Down
20 changes: 20 additions & 0 deletions src/data/Home.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//홈 화면에 나타나는 미션 카드 정보 (완료 전과 후 포함)
export type IHomeMission = {
dayOfWeek: string;
mission: string;
missionId: number;
missionStatus: string;
point: number;
storeCategory: string;
storeId: number;
storeName: string;
successDate: string;
};

//홈 화면을 채워줄 모든 데이터들
export type IHomeData = {
dday: number;
missions: IHomeMission[];
point: number;
rewards: number;
};
1 change: 1 addition & 0 deletions src/data/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './RegisterInterface';
export * from './createRegister';
export * from './MissionInterface';
export * from './Home';
12 changes: 7 additions & 5 deletions src/modal/SocialWebview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,22 @@ const SocialWebview: FC<SocialWebViewProps> = ({source, closeSocialModal}) => {
return params;
};

const storeData = async (value: string) => {
const storeData = async (accessToken: string, refreshToken: string) => {
try {
await AsyncStorage.setItem('userToken', value);
await AsyncStorage.multiSet([
['accessToken', accessToken],
['refreshToken', refreshToken],
]);
} catch (e) {
console.log(e);
}
};

const _handleMessage = async (data: any) => {
console.log(data);
const jwt = data.accessToken;
try {
await setToken(jwt);
await storeData(jwt);
await setToken(data.accessToken);
await storeData(data.accessToken, data.refreshToken);
} catch (e) {
console.log(e);
}
Expand Down
3 changes: 3 additions & 0 deletions src/nav/MyNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {MyPoint} from '../screens/my/MyPoint';
import {getFocusedRouteNameFromRoute} from '@react-navigation/native';
import {MyChangePoint} from '../screens/my/MyChangePoint';
import {MyChangePointDone} from '../screens/my/MyChangePointDone';
import {AuthNavigator} from './AuthNavigator';

export type MyStackParamList = {
MyPage: undefined;
Expand All @@ -19,6 +20,7 @@ export type MyStackParamList = {
MyInquiry: undefined;
MyChangePoint: undefined;
MyChangePointDone: undefined;
AuthNavigator: undefined;
};

const Stack = createStackNavigator<MyStackParamList>();
Expand Down Expand Up @@ -53,6 +55,7 @@ export const MyNavigator = ({navigation, route}) => {
<Stack.Screen name="MyInquiry" component={MyInquiry} />
<Stack.Screen name="MyChangePoint" component={MyChangePoint} />
<Stack.Screen name="MyChangePointDone" component={MyChangePointDone} />
<Stack.Screen name="AuthNavigator" component={AuthNavigator} />
</Stack.Navigator>
);
};
Loading

0 comments on commit 17629eb

Please sign in to comment.