NextJS/Next-Auth authentication
This is a simple demo project aiming to show how to realize a NextJS application able to load some credentials from a MongoDB collection and to keep a session until the user performs a logout action. The full code can be found on GitHub: https://github.com/fcalderan/nextjsauth-demo
The /pages/_app.js
file exports the function
import Layout from "../components/layout/layout";
import { SessionProvider } from "next-auth/react";
function MyApp({ Component, pageProps }) {
return (
<SessionProvider session={pageProps.session}>
<Layout>
<Component {...pageProps} />
</Layout>
</SessionProvider>
);
}
export default MyApp;
The Layout
component is wrapped into a SessionProvider
component, so it's available in all the components of the app.
The Login page can be accessed only when the user is not logged in and there is no session available. To check if a session is available we run the login page on server side through the getServerSideProps function. Since getSession
is asynchronous we use async/await
:
import { getSession } from "next-auth/react";
[...]
export async function getServerSideProps(context) {
const session = await getSession({ req: context.req });
if (session) {
return {
redirect: {
destination: "/profile",
permanent: false,
},
};
}
return {
props: { session },
};
}
If a session is available the user is redirected to the/profile
page. The top navigation is conditionally rendering some links based on the presence of the session.
import Link from "next/link";
import { useSession, signOut } from "next-auth/react";
import { useRouter } from "next/router";
import classes from "./main-navigation.module.css";
function MainNavigation() {
const router = useRouter();
const { data: session, status } = useSession();
return (
<header className={classes.header}>
<Link href="/" aria-current={router.pathname === "/" ? "page" : null}>
Next Auth
</Link>
<nav>
<ul>
{!session && (
<li>
<Link
href="/login"
aria-current={router.pathname === "/login" ? "page" : null}
>
Login
</Link>
</li>
)}
{session && (
<>
<li>
<Link
href="/profile"
aria-current={router.pathname === "/profile" ? "page" : null}
>
Profile
</Link>
</li>
<li>
<button onClick={signOut}>Logout</button>
</li>
</>
)}
</ul>
</nav>
</header>
);
}
export default MainNavigation;