AsyncStorage не устанавливает элемент в React Native с использованием Laravel Sanctum API

Я пытаюсь аутентифицировать своих пользователей, используя API-интерфейс святилища laravel в моем родном приложении.

Когда пользователь входит в систему или регистрируется, я сохраняю информацию в AsyncStorage.

Но похоже, что он не хранит информацию и не сохраняет ее постоянной. Например, когда я вхожу в систему, информация useState для userInfo верна и позволяет мне войти в систему, но всякий раз, когда я console.info AsyncStorage сохраненного useState userInfo, это то, что регистрируется. и когда я закрываю приложение и открываю его снова, оно возвращает меня обратно к экрану входа в систему, а не к экрану панели инструментов.

Как я могу использовать AsyncStorage, чтобы мои пользователи входили в систему и выходили из нее? Как удалить AsyncStorage, который я установил? Потому что всякий раз, когда я пытаюсь выйти из системы, используя мой маршрут API выхода, я получаю ошибку 401 axios.

Что я делаю неправильно и как заставить приложение использовать AsyncStorage для аутентификации (вход, регистрация, выход из системы)?

Вот мой код

API аутентификации Laravel:

 public function login(Request $request){

        $validator =  Validator::make($request->all(),[
            'email' => 'required|email|max:191',
            'password' => 'required',
        ]);

        if ($validator->fails()){
            return response()->json([
                'validation_errors' => $validator->messages(),
            ]);
        }else{
            $user = User::where('email', $request->email)->first();
 
            if (!$user || !Hash::check($request->password, $user->password)){
                return response()->json([
                    'status' => 401,
                    'message' => "Incorret Email or Password",
                ]);

            }else{
                //1 means admin
                if ($user->role_as == 1){
                    $role = 'admin';
                    $token = $user->createToken($user->email . '_token',['server:admin'])->plainTextToken;
                }else{
                    $role = '';
                    $token = $user->createToken($user->email . '_token',[''])->plainTextToken;
                }
               
                return response()->json([
                    'status' => 200,
                    'username' => $user->name,
                    'token' => $token,
                    'message' => 'Logged in Successfully',
                    'role' => $role
                ]); 
            }
        }
    }

    public function logout(){
        auth()->user()->tokens()->delete();
        return response()->json([
            'status' => 200,
            'message' => 'Logged out Successfully',
        ]); 
    }

App.js

//andorid
axios.defaults.baseURL = "http://10.0.2.2:8000/";
//ios
// axios.defaults.baseURL = "http://localhost:8000/";
axios.defaults.headers.post["Accept"] = "application/json";
axios.defaults.headers.post["Content-Type"] = "application/json";
axios.defaults.withCredentials = true;
axios.interceptors.request.use(function (config) {
    const token = AsyncStorage.getItem("auth_token");
    config.headers.Authorization = token ? `Bearer ${token}` : "";
    return config;
});

const App = () => {
  return (
    <Providers/>
  )
} 

Навигация.js

const Stack = createNativeStackNavigator();
const Navigation = () => {
  const { userInfo } = useContext(AuthContext);

  const user = AsyncStorage.getItem("userInfo");
  console.info(user);
  return (
    <NavigationContainer>
      {userInfo.username ? <AppStack /> : <AuthStack />}
    </NavigationContainer>
  );
};

AuthContext.js:

export const AuthContext = createContext();

export const AuthProvider = ({children}) => {
    const [userInfo, setUserInfo] = useState([])
    const [isLoading, setIsLoading] = useState(false)


 const login = async (email,password) => {
        axios.get("/sanctum/csrf-cookie").then((response) => {
            setIsLoading(true)
            axios.post("/api/login", {
                email,
                password
            }).then( async (res) => {
                if (res.data.status === 200) {
                    console.info(res.data)
                    setUserInfo(res.data)
                    AsyncStorage.setItem("userInfo", JSON.stringify(userInfo));
                    AsyncStorage.setItem("auth_token", res.data.token);
                    AsyncStorage.setItem("auth_name", res.data.username);
                    setIsLoading(false)
                } else if (res.data.status === 401) {
                    setLoginError(res.data.message)
                    setIsLoading(false)
                } else {
                    setLoginErrorList(res.data.validation_errors);
                    setIsLoading(false)
                }
            }).catch(e => {
                setIsLoading(false)
            });;
        });
    }

    const logout = () => {
        setIsLoading(true)
        
        axios.post("/api/logout").then((res) => {
            if (res.data.status === 200) {
                console.info(res.data)
                AsyncStorage.removeItem("auth_token")
                setUserInfo([])
                setIsLoading(false)
            }else{
                console.info("error")
            }

        }).catch(e => {
            console.info(e)
            setIsLoading(false)
        });;
    }


  return (
    <AuthContext.Provider value = {{
        isLoading,
        userInfo,
        registerErrorList,
        loginErrorList,
        loginError,
        register,
        login,
        logout,
        }}>
        {children}
    </AuthContext.Provider>
  )
};
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

@ Усама Джамал, посмотри, проблема, с которой ты сталкиваешься при ведении журнала консоли, заключается в том,

AsyncStorage.getItem() возвращает обещание, и если вы этого не сделаете await за его result , console.info, который вы получите, это Promise

Здесь

это обещание.

что вам нужно сделать здесь

const Stack = createNativeStackNavigator();
const Navigation = async() => {
  const { userInfo } = useContext(AuthContext);

  const user = await AsyncStorage.getItem("userInfo"); // add await here and on top make it an async function like i did in line 2
  console.info(user);
  return (
    <NavigationContainer>
      {userInfo.username ? <AppStack /> : <AuthStack />}
    </NavigationContainer>
  );
};

Надеюсь, это поможет. не стесняйтесь сомнений

Другие вопросы по теме