로그인 구현

This commit is contained in:
static
2024-12-26 19:08:28 +09:00
parent b6fbd83d6f
commit bd1cc9ea38
6 changed files with 44 additions and 7 deletions

View File

@@ -1,6 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte";
interface Props { interface Props {
children?: any; children: Snippet;
color?: "primary" | "gray"; color?: "primary" | "gray";
onclick?: () => void; onclick?: () => void;
} }

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte";
interface Props { interface Props {
children?: any; children: Snippet;
onclick?: () => void; onclick?: () => void;
} }

View File

@@ -35,13 +35,13 @@ const callAPIInternal = async (
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
}, },
}); });
if (res.status === 401 && retryIfUnauthorized) { if (res.status === 401 && retryIfUnauthorized && token !== undefined) {
return await callAPIInternal(input, init, null, false); return await callAPIInternal(input, init, null, false);
} }
return res; return res;
}; };
export const callAPI = async (input: RequestInfo, init?: RequestInit, token?: string | null) => { export default async (input: RequestInfo, init?: RequestInit, token?: string | null) => {
return await callAPIInternal(input, init, token); return await callAPIInternal(input, init, token);
}; };

1
src/lib/hooks/index.ts Normal file
View File

@@ -0,0 +1 @@
export { default as callAPI } from "./callAPI";

View File

@@ -1,6 +1,18 @@
<script lang="ts"> <script lang="ts">
import { Button, TextButton } from "$lib/components/buttons"; import { Button, TextButton } from "$lib/components/buttons";
import { TextInput } from "$lib/components/inputs"; import { TextInput } from "$lib/components/inputs";
import { requestLogin } from "./service";
let email = $state("");
let password = $state("");
const login = async () => {
// TODO: Validation
const ok = await requestLogin(email, password);
// TODO: Action
};
</script> </script>
<svelte:head> <svelte:head>
@@ -14,13 +26,13 @@
<p>서비스를 이용하려면 로그인을 해야해요.</p> <p>서비스를 이용하려면 로그인을 해야해요.</p>
</div> </div>
<div class="mt-4 flex flex-col gap-y-2"> <div class="mt-4 flex flex-col gap-y-2">
<TextInput placeholder="이메일" /> <TextInput bind:value={email} placeholder="이메일" />
<TextInput placeholder="비밀번호" type="password" /> <TextInput bind:value={password} placeholder="비밀번호" type="password" />
</div> </div>
</div> </div>
<div class="sticky bottom-0 flex w-full flex-col items-center gap-y-2"> <div class="sticky bottom-0 flex w-full flex-col items-center gap-y-2">
<div class="w-full"> <div class="w-full">
<Button>로그인</Button> <Button onclick={login}>로그인</Button>
</div> </div>
<div class="w-fit"> <div class="w-fit">
<TextButton>계정이 없어요</TextButton> <TextButton>계정이 없어요</TextButton>

View File

@@ -0,0 +1,21 @@
import { callAPI } from "$lib/hooks";
import { accessToken } from "$lib/stores/auth";
export const requestLogin = async (email: string, password: string) => {
const res = await callAPI("/api/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ email, password }),
});
if (!res.ok) {
return false;
}
const data = await res.json();
const token = data.accessToken as string;
accessToken.set(token);
return true;
};