middleware.ts 를 생성해 로그인 한 사용자와 로그인 안한 사용자를 구분하여 페이지 접속시 미리 구분 하여 페이지 접속 시 로그인 안한 사용자가 접근 불가한 페이지는 로그인 페이지로 이동하는 등 역할을 한다 .
export { auth as middleware } from "./auth";
export const config = {
matcher: ["/compose/tweet", "/home", "/explore", "/messages", "/search"],
};
import { signIn } from "next-auth/react";
const onSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
e.preventDefault();
setMessage("");
try {
const result = await signIn("credentials", {
username: id,
password,
redirect: false,
});
console.log(result);
router.replace("/home");
} catch (err) {
console.error(err);
setMessage("아이디와 비밀번호가 일치하지 않습니다.");
}
};
클라이언트 컴포넌트에서는 next-auth/react를 사용해서 하고
router.replace로 이동 시키든 한다.
서버 컴포넌트에서는 우리가 만든 auth.ts를 이용해 signIn을 하고
redirect를 이용해 이동 시키는 방법을 사용한다.
"use client";
import Image from "next/image";
import logo from "@/../public/logo.svg";
import { useRouter } from "next/navigation";
import { signOut, useSession } from "next-auth/react";
export default function LogoutButton() {
const router = useRouter();
const { data: me } = useSession();
const onLogout = () => {
signOut({ redirect: false }).then(() => {
router.replace("/");
});
if (!me?.user) {
return null;
}
};
return (
<button
className="fixed bottom-10 mt-auto py-2 px-10 flex justify-center items-center rounded-lg bg-amber-100 hover:bg-amber-200 cursor-pointer "
onClick={onLogout}
>
<div>
<Image
src={me?.user?.image as string}
alt="logo"
width={115}
height={120}
/>
</div>
<div className="xl:block hidden">
<p>{me?.user?.id}</p>
<p>@{me?.user?.name}</p>
</div>
</button>
);
}
클라이언트 컴포넌트라 next-auth/react을 사용해 import 하여 사용한다.
여기서 useSession은 로그인 된 정보를 가져올 수 있으며 클라이언트 컴포넌트에서
사용이 된다.
useSession을 사용하기 위해 sessionProvider를 감싸주어 사용하면 된다.
"use client";
import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";
export default function AuthSession({ children }: { children: ReactNode }) {
return <SessionProvider>{children}</SessionProvider>;
}
세션에 user정보가 있으면 home으로 가게하는 것 이것은 로그인 된 상태인데 로그인 페이지 및 beforelogin 페이지에 있으면 바로 home으로 보내줄 때 사용함.
const session = await auth();
if (session?.user) {
redirect("/home");
return null;
}
로그인 시 session-token이 생성됨. 또한 next-auth를 사용하면 csrf-token(자동 생성됨)을 통해 쿠키의 보안 위험성을 막아준다.
import { auth } from "./auth";
import { NextResponse } from "next/server";
export async function middleware() {
const session = await auth();
if (!session) {
return NextResponse.redirect("http://localhost:3000/flow/login");
}
}
// See "Matching Paths" below to learn more
export const config = {
matcher: ["/compose/tweet", "/home", "/explore", "/messages", "/search"],
};
미들 웨어에서 아래의 config에 있는 페이지를 접근할 떄 session을 통해 로그인 한 상태인지 아닌지 여부를 파악해 아니라면 flow/login 페이지로 보내는 것