Protected Pages
sebelumnya sudah membuat authentication, tapi belum sempurna jika belum ada halaman yang diproteksi
untuk membuat halaman protected bisa menggunakan middleware ataupun dengan component auth.
Middleware
Cara ini cukup simple karena kita hanya butuh membuat file bernama middleware.ts.
pertama buat file middlewarenya di root dengan nama ./middleware.ts
kemudian tulisakan
import { getToken } from 'next-auth/jwt';
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(req: NextRequest) {
const session = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
if (session) {
/**
* jika session tersedia maka izinkan untuk akses route
* apabila terdapat authorization bisa menambahkan logic disini
*/
return NextResponse.next();
}
/**
* jika session tidak tersedia maka redirect ke login page(/auth/login)
*/
return NextResponse.redirect(new URL('/', req.url));
}
/**
* menetapkan path dimana middleware akan dijalakan
* sebagai contoh dibawah ini
* middleware akan dijalankan ketika pengguna mengakses halaman yang berawalan /admin/..
* contoh: /admin/a, /admin/a/b
*/
export const config = {
/**
* untuk matcher dapat menggunakan
* /:path* atau /(.*)
*/
matcher: '/admin/:path*',
};
Didalam function getToken diatas terdapat sebuah secret yang digunakan untuk key dari session agar ketika session diambil bisa berjalan dengan lancar. maka dari itu buat terlebih dahulu keynya pada file .env pada directory root
NEXTAUTH_SECRET=secret-kamu
kemudian buka file pages/api/auth/[...nextauth].ts dan tambahkan properti secret
pages: {
signIn: '/auth/login',
signOut: '/auth/register',
error: '',
newUser: null,
},
/**
* tambahkan disini
*/
secret: process.env.NEXTAUTH_SECRET,
Component Auth
Cara kedua yaitu dengan menggunakan Component.
Pertama ubah kode pages/_app.tsx seperti dibawah
import "@/styles/globals.css";
import React from "react";
import { SessionProvider, useSession } from "next-auth/react";
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session}>
{/* jika component memiliki value auth maka setiap route akan di validasi */}
{Component?.auth.protected ? (
<Auth>
<Component {...pageProps} />
</Auth>
) : (
<Component {...pageProps} />
)}
</SessionProvider>
);
}
function Auth({ children }) {
const session = useSession({ required: true });
/**
* bisa ditambahkan logic untuk cek session
*/
if (session.status === "loading") {
return <div>loading .....</div>;
}
return children;
}
kemudian pada masing masing komponent tambahkan property auth seperti dibawah ini
import React from "react";
import { signOut } from "next-auth/react";
import { useRouter } from "next/router";
export default function Admin() {
const router = useRouter();
const handleSignOut = async () => {
await signOut().then(() => router.push("/auth/login"));
};
return (
<div>
<h3>admin</h3>
<button onClick={handleSignOut}>Signout</button>
</div>
);
}
Admin.auth = {
protected: true,
// additional authentication
// role: 'admin',
// unauthorized: '/login-user',
};