Skip to main content

6. Creating the Configuration Files

Now in the root of the project, let's create a file called process.d.ts. This file is responsible for adding the environment variables that we created previously. So, add the following code:

  • process.d.ts
process.d.ts

declare namespace NodeJS {
export interface ProcessEnv {
NEXTAUTH_URL: string;
NEXTAUTH_SECRET: string;
AZURE_AD_CLIENT_SECRET: string;
AZURE_AD_CLIENT_ID: string;
}
}

When in the project we have some protected routes/pages, we need to create a file called: middleware.ts. We just can access these protected routes/pages if we are authenticated. So, let's create this file and add the following code:

  • middleware.ts
middleware.ts
import { withAuth } from 'next-auth/middleware';

export default withAuth({
callbacks: {
authorized({ req, token }) {
if (req.nextUrl.pathname === '/admin') {
return token?.userRole === 'admin';
}

return !!token;
},
},
});

export const config = { matcher: ['/reminder'] };

Let's understand what is happening here. First, we are importing the withAuth function from the next-auth/middleware package. This function is responsible for protecting the routes/pages that we want. Then, we are exporting the withAuth function with the callbacks property. This property is responsible for checking if the user is authenticated or not. So, if the user is authenticated, we can access the protected pages. If the user is not an admin user, we can't access the /admin page. And if the user is not authenticated, we can't access the /reminder page. Just if it is logged in.

If you want to know more about the middleware.ts file, you can check the documentation of the next-auth.

We need to make some important changes in the admin.tsx file. So, let's add the following code:

  • pages/admin.tsx
pages/admin.tsx

import { useState, useEffect } from 'react';
import { useSession } from 'next-auth/react';
import Layout from '../components/Layout/layout';
import AccessDenied from '../components/AccessDenied/access-denied';

export default function Page() {
const { data: session } = useSession();
const [content, setContent] = useState();

useEffect(() => {
const fetchData = async () => {
const res = await fetch('/api/examples/admin-protected');
const json = await res.json();
if (json.content) {
setContent(json.content);
}
};

fetchData();
}, [session]);

if (!session) {
return (
<Layout>
<AccessDenied />
</Layout>
);
}

return (
<Layout>
<h1>Admin Page</h1>
<p>
<strong>{content ?? '\u00a0'}</strong>
</p>
</Layout>
);
}

Next step, inside the api folder let's create a folder called examples. And inside this folder, let's create a file called admin-protected.ts. So, add the following code:

  • api/examples/admin-protected.ts
api/examples/admin-protected.ts

import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "../auth/[...nextauth]"

import type { NextApiRequest, NextApiResponse } from "next"

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const session = await unstable_getServerSession(req, res, authOptions)

if (session) {
return res.send({
content:
"This is protected page. You can access this page because you are signed in.",
})
}

res.send({
error: "You must be signed in to view the protected page.",
})
}

And inside the examples folder, let's create a file called session.ts. So, add the following code:

  • api/examples/session.ts
api/examples/session.ts

import { unstable_getServerSession } from "next-auth";
import { authOptions } from "../auth/[...nextauth]";

import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const session = await unstable_getServerSession(req, res, authOptions);
res.send(JSON.stringify(session, null, 2));
}

Phew! We are almost done! However, there's some important changes that we need to do in the Admin and Reminder pages. Let's see this in the next session!