세션에서 상태 불러오기
세션에서 상태 불러오기
로그인 정보를 유지하려면 브라우저 세션에 저장하고 불러와야 합니다. 이를 위해 쿠키나 로컬 스토리지를 사용할 수 있습니다. 다행히 AWS Amplify가 이를 자동으로 처리해 주기 때문에, 우리는 단순히 이를 읽어와 애플리케이션 상태에 로드하기만 하면 됩니다.
Amplify는 Auth.currentSession()
메서드를 통해 현재 사용자 세션을 가져올 수 있는 방법을 제공합니다. 이 메서드는 세션 객체(존재하는 경우)로 resolve되는 Promise를 반환합니다.
사용자 세션 불러오기
앱이 로드될 때 사용자 세션을 불러오도록 해봅시다. 이를 위해 React의 또 다른 훅인 useEffect
를 사용할 것입니다. Auth.currentSession()
이 Promise를 반환하기 때문에, 이 작업이 완료된 후에만 앱의 나머지 부분이 준비되도록 해야 합니다.
이를 위해 src/App.tsx
의 상태에 isAuthenticating
이라는 새로운 상태 변수를 추가합니다. App
함수의 상단에 추가합니다.
const [isAuthenticating, setIsAuthenticating] = useState(true);
앱이 처음 로드될 때 인증 상태를 확인하는 과정에서 시작되므로 초기값을 true
로 설정합니다.
사용자 세션을 불러오기 위해 src/App.tsx
의 변수 선언 바로 아래에 다음 코드를 추가합니다.
useEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
await Auth.currentSession();
userHasAuthenticated(true);
} catch (e) {
if (e !== "No current user") {
alert(e);
}
}
setIsAuthenticating(false);
}
그런 다음 src/App.tsx
의 헤더에 Auth
모듈을 추가합니다.
import { Auth } from "aws-amplify";
useEffect
훅을 포함시키기 위해 src/App.tsx
의 헤더에서 React import를 다음과 같이 변경합니다.
import { useState, useEffect } from "react";
이제 useEffect
훅이 어떻게 동작하는지 이해해봅시다.
useEffect
훅은 함수와 변수 배열을 인자로 받습니다. 이 함수는 컴포넌트가 렌더링될 때마다 호출됩니다. 그리고 변수 배열은 전달된 배열의 변수가 변경되었을 때만 함수를 다시 실행하도록 React에 지시합니다. 이를 통해 함수가 실행되는 시점을 제어할 수 있습니다. 이는 몇 가지 흥미로운 결과를 가져옵니다:
- 변수 배열을 전달하지 않으면, 컴포넌트가 렌더링될 때마다 훅이 실행됩니다.
- 일부 변수를 전달하면, React는 렌더링할 때마다 해당 변수가 변경되었는지 확인한 후에 함수를 실행합니다.
- 빈 배열을 전달하면, 첫 번째 렌더링 시에만 함수가 실행됩니다.
이 경우, 앱이 처음 로드될 때만 사용자의 인증 상태를 확인하고 싶습니다. 따라서 세 번째 옵션을 사용합니다. 빈 배열 []
을 전달하면 됩니다.
앱이 처음 로드될 때 onLoad
함수가 실행됩니다. 이 함수는 현재 세션을 불러오는 역할을 합니다. 세션이 성공적으로 불러와지면, isAuthenticating
상태 변수를 업데이트합니다. 이는 setIsAuthenticating(false)
를 호출하여 수행됩니다. Auth.currentSession()
메서드는 현재 로그인한 사용자가 없을 때 No current user
오류를 발생시킵니다. 사용자가 앱을 로드했을 때 로그인하지 않은 상태라면 이 오류를 사용자에게 보여주고 싶지 않습니다. Auth.currentSession()
이 성공적으로 실행되면, userHasAuthenticated(true)
를 호출하여 사용자가 로그인했음을 설정합니다.
따라서 App
함수의 상단은 이제 다음과 같이 보일 것입니다:
function App() {
const [isAuthenticating, setIsAuthenticating] = useState(true);
const [isAuthenticated, userHasAuthenticated] = useState(false);
useEffect(() => {
onLoad();
}, []);
...
상태가 준비되었을 때 렌더링하기
사용자 세션을 불러오는 과정은 비동기적이므로, 앱이 처음 로드될 때 상태가 변경되지 않도록 해야 합니다. 이를 위해 isAuthenticating
이 false
가 될 때까지 앱 렌더링을 지연시킬 것입니다.
isAuthenticating
플래그를 기반으로 앱을 조건부로 렌더링합니다.
src/App.tsx
의 return
문을 다음 코드로 교체하세요.
return (
!isAuthenticating && (
<div className="App container py-3">
<Navbar collapseOnSelect bg="light" expand="md" className="mb-3 px-3">
<LinkContainer to="/">
<Navbar.Brand className="fw-bold text-muted">Scratch</Navbar.Brand>
</LinkContainer>
<Navbar.Toggle />
<Navbar.Collapse className="justify-content-end">
<Nav activeKey={window.location.pathname}>
{isAuthenticated ? (
<Nav.Link onClick={handleLogout}>Logout</Nav.Link>
) : (
<>
<LinkContainer to="/signup">
<Nav.Link>Signup</Nav.Link>
</LinkContainer>
<LinkContainer to="/login">
<Nav.Link>Login</Nav.Link>
</LinkContainer>
</>
)}
</Nav>
</Navbar.Collapse>
</Navbar>
<AppContext.Provider
value={{ isAuthenticated, userHasAuthenticated } as AppContextType}
>
<Routes />
</AppContext.Provider>
</div>
)
);
이제 브라우저로 이동해 페이지를 새로고침하면 사용자가 로그인된 상태로 표시됩니다.
하지만 로그아웃을 한 후 페이지를 새로고침하면 여전히 로그인 상태로 남아 있습니다. 이 문제를 해결하기 위해 다음으로 로그아웃 시 세션을 초기화할 것입니다.
For help and discussion
Comments on this chapter