How to implement Authententication with AuthJS v5 (Next-Auth) using Google OAuth
Hi! I strugled 2 days on implementing basic Authentication using AuthJs v5 library with Google OAuth for Nextjs application. So. i thought be good to show how to make it and use it for reference. Many thing will come up from documentation. I assume that you intialized next project already.
Â
Table of Contents
Install AuthJs v5
Install library
npm install next-auth@beta
Add Auth environment variable
npx auth secret
Add generated string to
.env
fileAUTH_SECRET="Your generated secret"
Create auth.js / auth.ts (if you use Typescript)
import NextAuth from "next-auth"
import Google from "next-auth/providers/google"
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [Google],
})
 Create ./app/api/auth/[...nextauth]/route.js / route.ts
 Add in route:
import { handlers } from "@/auth"
export const { GET, POST } = handlers
Add middleware.js / .ts
export { auth as middleware } from "@/auth"
// Don't invoke middleware in some paths
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}
Set-up Google OAuth
Create project on Google developers console
Create project on Google Developer Console in OAuth Consent screen.
You need Client ID and Client Screen and add http://localhost:3000/api/auth/callback/google to Authrised redirect Uri'sÂ
(See photo below)
Add ID and Secret to .env file
AUTH_GOOGLE_ID={CLIENT_ID}
AUTH_GOOGLE_SECRET={CLIENT_SECRET}
Add this variables to your .env
file
How to use sign in and sign out
Using server-side component (non interactive)
Sign In
import { signIn } from "@/auth"
export default function SignIn() {
return (
<form
action={async () => {
"use server"
await signIn("google")
}}
>
<button type="submit">Signin with Google</button>
</form>
)
}
Sign Out same as Sign in
import { signOut } from "@/auth"
export default function SignOut() {
return (
<form
action={async () => {
"use server"
await signOut();
}}
>
<button type="submit">Sign Out</button>
</form>
)
}
Using client side component ("use client", interactive page)
Sign In
"use client";
import { signIn } from "next-auth/react";
const SignIn = () => {
const handleClick = async () => {
await signIn("google");
};
return (
<button className="btn" onClick={handleClick}>
Sign In
</button>
);
};
export default SignIn;
Sign Out same as Sign in
"use client";
const SignOut = () => {
const handleClick = async () => {
await signOut();
};
return (
<button onClick={handleClick} className="btn">
Sign Out
</button>
);
};
export default SignOut;
How to protect route
Add Session Provider to your Layout, to have access to data
import "@/styles/globals.css";
import { auth } from "@/auth";
import { SessionProvider } from "next-auth/react";
export const metadata = {
title: "Project",
description: "Project",
};
export default async function RootLayout({ children }) {
const session = await auth();
return (
<html lang="en">
<body>
<SessionProvider session={session}>
<main>{children}</main>
</SessionProvider>
</body>
</html>
);
}
Add redirect if user not authenticated.Â
"use client";
import { redirect } from "next/navigation";
import { useSession } from "next-auth/react";
const ProtectedRoute = () => {
const { data: session } = useSession();
if (!session) return redirect("/login");
return (
<div>
This is protected route
</div>
);
};
export default ProtectedRoute;
That's it.
Â