Skip to main content

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',
};