1. 로그인
로그인은 사용자의 username(또는 email)과 password를 백엔드로 전송해서
Access Token(여기서는 JWT를 사용)를 얻는다.
이렇게 얻은 Access Token을 관리하는 방법은 여러 가지가 있지만, 여기서는 usehooks-ts의
useLocalStorage를 사용해서 전역적으로 동기화한다.
LoginFormStore를 이용해 로그인한다. 로그인에 성공하면
accessToken
을 발급받는다. 로컬 스토리지에 set하는 것 까지 이뤄진다.useAccessToken 으로 accessToken을 ApiService 내부에 저장하고 매 요청마다 첨부한다.
LoginFormStore.ts
import { singleton } from "tsyringe";
import { Action, Store } from "usestore-ts";
import { apiService } from "../services/ApiService";
@singleton()
@Store()
export default class LoginFormStore {
email = "";
password = "";
error = false;
accessToken = "";
get valid() {
return this.email.includes("@") && !!this.password;
}
@Action()
changeEmail(email: string) {
this.email = email;
}
@Action()
changePassword(password: string) {
this.password = password;
}
@Action()
private setAccessToken(accessToken: string) {
this.accessToken = accessToken;
}
@Action()
private setError() {
this.error = true;
}
@Action()
reset() {
this.email = "";
this.password = "";
this.error = false;
this.accessToken = "";
}
async login() {
try {
const accessToken = await apiService.login({
email: this.email,
password: this.password,
});
this.setAccessToken(accessToken);
} catch (e) {
this.setError();
}
}
}
useAccessToken
import { useEffect } from "react";
import { useLocalStorage } from "usehooks-ts";
import { apiService } from "../services/ApiService";
export default function useAccessToken() {
const [accessToken, setAccessToken] = useLocalStorage("accessToken", "");
useEffect(() => {
apiService.setAccessToken(accessToken);
}, [accessToken]);
return { accessToken, setAccessToken };
}
routes.test.tsx 에서 로그인 test
context("when the current path is “/login", () => {
it("renders the login page", async () => {
renderRouter("/login");
screen.getByRole("heading", { name: "로그인" });
fireEvent.change(screen.getByLabelText("E-mail"), {
target: { value: "tester@example.com" },
});
fireEvent.change(screen.getByLabelText("Password"), {
target: { value: "password" },
});
fireEvent.click(screen.getByRole("button", { name: "로그인" }));
await waitFor(() => {
screen.getByText(/Orders/);
screen.getByText(/Cart/);
screen.getByText(/Logout/);
});
});
});
useAccessToken 훅을 이용해 손쉽게 로그인 여부를 알 수 있다.
const Container = styled.div`
margin-bottom: 2rem;
line-height: 1.8;
`;
export default function AddToCartForm() {
const { accessToken } = useAccessToken(); //
if (!accessToken) {
return (
<Container>
{/* 주문하려면 <Link to="/login?redirect_to=/productfsd">로그인</Link> 원래 있던 주소로 돌아가는거*/}
주문하려면 <Link to="/login">로그인</Link>
하세요
</Container>
);
}
return (
<Container>
<Options />
<Quantity />
<Price />
<SubmitButton />
</Container>
);
}
Last updated