useContext API를 사용하여 반응 시 인증 상태 관리

王林
풀어 주다: 2024-09-08 22:34:33
원래의
813명이 탐색했습니다.

Managing Auth State in react using useContext API

이 코드 조각은 React 애플리케이션에서 인증 상태를 관리하는 데 필요한 모든 것입니다. Context API를 사용하여 애플리케이션 전체에서 사용자 상태를 관리합니다.

더 이상 잡담하지 말고 본격적으로 살펴보겠습니다.

가져오기 및 유형 정의

import { createContext, Dispatch, ReactNode, SetStateAction, useContext, useEffect } from "react";
import { useLocalStorage } from "../utils/useLocalStorage";

type SignInForm = { email: string; password: string; };
type User = { id: number; email: string; };
type AuthState = User & { exp: number };
type UserContextType = {
  user: User | null;
  setUser: Dispatch<SetStateAction<AuthState | null>>;
  signOut: () => Promise<string | undefined>;
  signIn: (signInForm: SignInForm) => Promise<string | undefined>;
};
로그인 후 복사

필요한 React 후크와 사용자 정의 useLocalStorage 후크를 가져오는 것부터 시작합니다. 그런 다음 SignInForm, User, AuthState 및 UserContextType을 포함하여 인증 시스템에 대한 TypeScript 유형을 정의합니다.

컨텍스트 및 사용자 정의 Hook 생성

const AuthDataContext = createContext<UserContextType | undefined>(undefined);

export const useAuth = (): UserContextType => {
  const context = useContext(AuthDataContext);
  if (!context) {
    throw new Error("useAuth must be used within a UserDataProvider");
  }
  return context;
};
로그인 후 복사

여기에서는 AuthDataContext와 사용자 정의 useAuth 후크를 생성합니다. 이 후크는 공급자 내의 컨텍스트를 사용하고 인증 상태에 액세스하는 편리한 방법을 제공합니다.

인증 제공자 구성요소

export const AuthProvider = ({ children }: { children: ReactNode }) => {
  const [user, setUser] = useLocalStorage<AuthState | null>("user", null);

  // ... (other functions)

  return (
    <AuthDataContext.Provider value={{ user, setUser, signIn, signOut }}>
      {children}
    </AuthDataContext.Provider>
  );
};
로그인 후 복사

AuthProvider 구성 요소는 인증 시스템의 핵심입니다. useLocalStorage 후크를 사용하여 사용자 상태를 유지하고 하위 항목에 컨텍스트 값을 제공합니다.

JWT 만료 확인

const isJwtExpired = (unixTime: number) => {
  const currentTime = Math.floor(Date.now() / 1000);
  const timeRemaining = unixTime - currentTime;
  if (timeRemaining <= 0) {
    console.log("The JWT is expired.");
    setUser(null);
    return true;
  } else {
    const hours = Math.floor(timeRemaining / 3600);
    const minutes = Math.floor((timeRemaining % 3600) / 60);
    console.log(`Time remaining before JWT expires: ${hours} hours ${minutes} minutes`);
    return false;
  }
};
로그인 후 복사

JWT가 만료되었는지 확인하고, 아직 유효한 경우 남은 시간을 기록하는 기능입니다.

로그아웃 기능

const signOut = async () => {
  const res = await fetch("http://localhost:8080/auth/signout", { method: "POST" });
  setUser(null);
  if (!res.ok) {
    console.log("Error signing out");
    return (await res.text()) || "Something went wrong";
  }
};
로그인 후 복사

signOut 함수는 로그아웃 엔드포인트에 POST 요청을 보내고 사용자 상태를 지웁니다.

로그인 기능

const signIn = async (signInForm: SignInForm) => {
  const res = await fetch("http://localhost:8080/auth/signin", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(signInForm),
  });
  if (!res.ok) {
    return (await res.text()) || "Something went wrong";
  }
  const data = (await res.json()) as { user: User; exp: number };
  if (data) {
    setUser({ ...data.user, exp: data.exp });
  }
};
로그인 후 복사

signIn 함수는 사용자의 자격 증명을 로그인 엔드포인트로 보내고 응답 데이터로 사용자 상태를 업데이트합니다.

JWT 만료 확인을 위한 useEffect

useEffect(() => {
  if (!user) return;
  if (isJwtExpired(user.exp)) signOut();
}, [user]);
로그인 후 복사

이 효과는 사용자 상태가 변경될 때마다 실행되어 JWT가 만료되었는지 확인하고 필요한 경우 로그아웃합니다.

다음은 useLocalStorage 후크 구현의 예입니다

import { useState, useEffect, Dispatch, SetStateAction } from "react";

export function useLocalStorage<T>(
  key: string,
  initialValue: T
): [T, Dispatch<SetStateAction<T>>] {
  const [storedValue, setStoredValue] = useState<T>(() => {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.log(error);
      return initialValue;
    }
  });

  const setValue: Dispatch<SetStateAction<T>> = (value) => {
    try {
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    const handleStorageChange = (event: StorageEvent) => {
      if (event.key === key) {
        setStoredValue(JSON.parse(event.newValue || "null"));
      }
    };

    window.addEventListener("storage", handleStorageChange);
    return () => window.removeEventListener("storage", handleStorageChange);
  }, [key]);

  return [storedValue, setValue];
}
로그인 후 복사

끝났나요? easy peasy 레몬 스퀴지.. 필요한 경우 자신의 API 구조에 대한 가져오기 논리를 수정하세요.

위 내용은 useContext API를 사용하여 반응 시 인증 상태 관리의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!