AuthProvider.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import { ReactNode, createContext, useEffect, useState } from 'react';
  2. import { useContext } from 'react';
  3. import { router, useSegments } from 'expo-router';
  4. import * as SecureStore from 'expo-secure-store';
  5. import axios from 'axios';
  6. import { EXPO_PUBLIC_API_URL } from '@env';
  7. import { User } from '../types/user';
  8. import { authenticationService } from '../service/authService';
  9. type AuthProvider = {
  10. user: User | null;
  11. login: (username: string, password: string) => Promise<boolean>;
  12. logout: () => void;
  13. setUser: React.Dispatch<React.SetStateAction<User | null>>;
  14. };
  15. function useProtectedRoute(user: User | null) {
  16. const segments = useSegments();
  17. useEffect(() => {
  18. const inAuthGroup = segments[0] === '(auth)';
  19. if (!user && inAuthGroup) {
  20. router.replace('/login');
  21. } else if (user && !inAuthGroup) {
  22. router.replace('/(auth)/(tabs)/(home)/mainPage');
  23. }
  24. }, [user, segments]);
  25. }
  26. export const AuthContext = createContext<AuthProvider>({
  27. user: null,
  28. login: async () => false,
  29. logout: () => {},
  30. setUser: () => {}
  31. });
  32. export function useAuth() {
  33. const context = useContext(AuthContext);
  34. if (!context) {
  35. throw new Error('useAuth must be used within a <AuthProvider />');
  36. }
  37. return context;
  38. }
  39. export default function AuthProvider({ children }: { children: ReactNode }) {
  40. const [user, setUser] = useState<User | null>(null);
  41. const login = async (username: string, password: string) => {
  42. try {
  43. const loggedInUser = await authenticationService.login(
  44. username,
  45. password
  46. );
  47. if (loggedInUser) {
  48. const userInfo = await getUserFromAccessToken();
  49. if (userInfo) {
  50. setUser((prevUser) => ({
  51. ...prevUser,
  52. address: userInfo.address,
  53. birthday: userInfo.birthday,
  54. email: userInfo.email,
  55. gender: userInfo.gender,
  56. nickname: userInfo.nickname,
  57. phone: userInfo.phone
  58. }));
  59. }
  60. return true;
  61. } else {
  62. return false;
  63. }
  64. } catch (error) {
  65. console.error('Login error:', error);
  66. return false;
  67. }
  68. };
  69. const getUserFromAccessToken = async () => {
  70. const token = await SecureStore.getItemAsync('accessToken');
  71. try {
  72. const res = await axios.get(
  73. `${EXPO_PUBLIC_API_URL}/clients/customer`,
  74. {
  75. headers: {
  76. Authorization: `Bearer ${token}`
  77. }
  78. }
  79. );
  80. const items = {
  81. address: res.data.address,
  82. birthday: res.data.birthday,
  83. gender: res.data.gender,
  84. email: res.data.email,
  85. nickname: res.data.nickname,
  86. phone: res.data.phone
  87. };
  88. return items;
  89. } catch (error) {
  90. console.error('GetUser Error:', error);
  91. }
  92. };
  93. const logout = async () => {
  94. try {
  95. await authenticationService.logout();
  96. setUser(null);
  97. router.replace('/login');
  98. } catch (error) {
  99. console.log('error during logout', error);
  100. }
  101. };
  102. useProtectedRoute(user);
  103. return (
  104. <AuthContext.Provider value={{ user, login, logout, setUser }}>
  105. {children}
  106. </AuthContext.Provider>
  107. );
  108. }