Next JS 14 Authentication | Protected Routes | Google SignIn in Next JS Using NextAuth

Free


Steps for adding Next JS 14 Authentication | Protected Routes | Google SignIn in Next JS Using NextAuth


Next JS

Snapshots


Steps for adding Next JS 14 Authentication | Protected Routes | Google SignIn in Next JS Using NextAuth

1. Install NextAuth
npm install next-auth



2. These Files Need to be created

Go to 'src\app\api\auth\[...nextauth]' and create
options.ts
route.ts


3. Update 'options.ts' File

import type { NextAuthOptions } from "next-auth";
import GitHubProvider from "next-auth/providers/github";
import CredentialsProvider from "next-auth/providers/credentials";
import GoogleProvider from "next-auth/providers/google";

export const options: NextAuthOptions = {
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_ID as string,
      clientSecret: process.env.GITHUB_SECRET as string,
    }),
    GoogleProvider({
      clientId: process.env.NEXT_GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.NEXT_GOOGLE_CLIENT_SECRET as string,
    }),
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        username: {
          label: "Username:",
          type: "text",
          placeholder: "Enter Username",
        },
        password: {
          label: "Password:",
          type: "password",
          placeholder: "Enter Password",
        },
      },
      async authorize(credentials) {
        // This is where you need to retrieve user data
        // to verify with credentials
        // Docs: https://next-auth.js.org/configuration/providers/credentials
        const user = { id: "42", name: "codingmstr", password: "codingmstr" };

        if (
          credentials?.username === user.name &&
          credentials?.password === user.password
        ) {
          return user;
        } else {
          return null;
        }
      },
    }),
  ],
};



4. Update 'route.ts' File

import NextAuth from 'next-auth'
import { options } from './options'

const handler = NextAuth(options)

export { handler as GET, handler as POST }


5. Go to 'src\app\context' and create
Authprovider.tsx


6. Update 'Authprovider.tsx' File

"use client";

import { SessionProvider } from "next-auth/react";

export default function AuthProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return <SessionProvider>{children}</SessionProvider>;
}



7. Modify root 'Layout.tsx' or 'Layout.jsx' file
Go to 'src\app\Layout.tsx'

import AuthProvider from "./context/AuthProvider";

        <body className={inter.className}>
           <AuthProvider>{children}</AuthProvider>
        </body>




8. Modify Login Page and add Google Login Button

"use client";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { signIn } from "next-auth/react";
import { useSession } from 'next-auth/react';
import { redirect } from 'next/navigation';
// import { setCookie, deleteCookie } from "cookies-next";


export default function Home() {
  const router = useRouter();
  const { data: session } = useSession();

  if (session) {
    let user = session["user"];
    console.log('Session User ', user);
    // setCookie("logged", "true", { maxAge: 60 * 60 * 24 * 30 });
    redirect('/dashboard');
  }

  return (
    <>
      <div className="flex justify-center mt-16">
        <div style={{ minWidth: "30%" }}>
          <div className="shadow-lg flex min-h-full flex-1 flex-col
justify-center px-6 py-12 lg:px-8 bg-white">
            <div className="sm:mx-auto sm:w-full sm:max-w-sm">
              <div className="flex justify-center">
                <Image src="/login.gif" height={70} width={70} />
              </div>
              <h2 className="mt-10 text-center text-2xl font-bold leading-9
tracking-tight text-gray-900">
                Sign in to your account
              </h2>
            </div>

            <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
              <form className="space-y-6" action="#" method="POST">
                <div>
                  <label
                    htmlFor="email"
                    className="block text-sm font-medium leading-6 text-gray-900"
                  >
                    Email address
                  </label>
                  <div className="mt-2">
                    <input
                      id="email"
                      name="email"
                      type="email"
                      autoComplete="email"
                      className="block w-full rounded-md border-0 py-1.5
text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300
placeholder:text-gray-400 focus:ring-2 focus:ring-inset
focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    />
                  </div>
                </div>

                <div>
                  <div className="flex items-center justify-between">
                    <label
                      htmlFor="password"
                      className="block text-sm font-medium leading-6 text-gray-900"
                    >
                      Password
                    </label>
                    <div className="text-sm">
                      <a
                        href="#"
                        className="font-semibold text-indigo-600 hover:text-indigo-500"
                      >
                        Forgot password?
                      </a>
                    </div>
                  </div>
                  <div className="mt-2">
                    <input
                      id="password"
                      name="password"
                      type="password"
                      autoComplete="current-password"
                      className="block w-full rounded-md border-0 py-1.5
text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 p
laceholder:text-gray-400 focus:ring-2 focus:ring-inset
focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    />
                  </div>
                </div>
                <div>
                  <button
                    onClick={() => {
                      router.push("/dashboard");
                    }}
                    className="flex w-full justify-center
rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6
text-white shadow-sm hover:bg-indigo-500 focus-visible:outline
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
                  >
                    Sign in
                  </button>
                </div>
                <div>
                  <button
                    onClick={() => signIn("google")}
                    className="flex w-full justify-center rounded-md bg-indigo-600 px-3
py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500
focus-visible:outline focus-visible:outline-2
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
                  >
                    <div className="flex">
                      Sign in with Google
                      <span className="mx-3">
                        <svg
                          width="24"
                          height="24"
                          viewBox="0 0 24 24"
                          fill="none"
                          xmlns="http://www.w3.org/2000/svg"
                        >
                          <rect width="24" height="24" fill="none" />
                          <path
                            fillRule="evenodd"
                            clipRule="evenodd"
                            d="M23.04 12.2614C23.04 11.4459 22.9668 10.6618
22.8309 9.90909H12V14.3575H18.1891C17.9225 15.795 17.1123 17.013 15.8943
17.8284V20.7139H19.6109C21.7855 18.7118 23.04 15.7636 23.04 12.2614Z"
                            fill="#4285F4"
                          />
                          <path
                            fillRule="evenodd"
                            clipRule="evenodd"
                            d="M12 23.4998C15.105 23.4998 17.7081 22.4701 19.6109
20.7137L15.8943 17.8282C14.8645 18.5182 13.5472 18.926 12 18.926C9.00474 18.926 6.
46951 16.903 5.56519 14.1848H1.72314V17.1644C3.61542 20.9228 7.50451 23.4998 12 23.4998Z"
                            fill="#34A853"
                          />
                          <path
                            fillRule="evenodd"
                            clipRule="evenodd"
                            d="M5.56523 14.1851C5.33523 13.4951 5.20455 12.758
5.20455 12.0001C5.20455 11.2421 5.33523 10.5051 5.56523
9.81506V6.83551H1.72318C0.944318 8.38801 0.5 10.1444 0.5 12.0001C0.5 13.8557
0.944318 15.6121 1.72318 17.1646L5.56523 14.1851Z"
                            fill="#FBBC05"
                          />
                          <path
                            fillRule="evenodd"
                            clipRule="evenodd"
                            d="M12 5.07386C13.6884 5.07386 15.2043 5.65409 16.3961
6.79364L19.6945 3.49523C17.7029 1.63955 15.0997 0.5 12 0.5C7.50451 0.5 3.61542
3.07705 1.72314 6.83545L5.56519 9.815C6.46951 7.09682 9.00474 5.07386 12 5.07386Z"
                            fill="#EA4335"
                          />
                        </svg>
                      </span>

                    </div>
                  </button>
                </div>
              </form>

              <p className="mt-10 text-center text-sm text-gray-500">
                Not a member?{" "}
                <span
                  className="font-semibold leading-6 text-indigo-600 hover:text-indigo-500
cursor-pointer"
                  onClick={() => {
                    router.push("/signup");
                  }}
                >
                  Start a 14 day free trial
                </span>
              </p>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}




9. Modify Protected Routes

import LogoutIcon from '@mui/icons-material/Logout';
import { useSession, signOut } from 'next-auth/react';
import { redirect } from 'next/navigation';


  const { data: session } = useSession({
    required: true,
    onUnauthenticated() {
      redirect('/')
      // redirect('/api/auth/signin?callbackUrl=/client')
    }
  })


  if (session) {
    let user = session["user"];
    console.log('Session User ', user);
  }

  const userLogout = () => {
    signOut();
  }



      <AppBar
        position="fixed"
        sx={{
          width: { sm: `calc(100% - ${drawerWidth}px)` },
          ml: { sm: `${drawerWidth}px` },
          bgcolor: "#FFFFFF",
          color: "#2f2f2f",
        }}
      >
        <div className="flex justify-between">
          <Toolbar>
            <IconButton
              color="inherit"
              aria-label="open drawer"
              edge="start"
              onClick={handleDrawerToggle}
              sx={{ mr: 2, display: { sm: "none" } }}
            >
              <MenuIcon />
            </IconButton>

            <Typography variant="h6" noWrap component="div">
              Dashboard
            </Typography>
          </Toolbar>
          <div className="mt-3 mr-3 cursor-pointer" onClick={() => userLogout()}>
            <Typography variant="h6" noWrap component="div">
              <LogoutIcon /> Logout
            </Typography>
          </div>
        </div>
      </AppBar>



STEPS TO SET UP GOOGLE LOGIN


10. Create .env file and followinf lines

NEXT_GOOGLE_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxx
NEXT_GOOGLE_CLIENT_SECRET=xxxxxxxxxxxxxxxxx
NEXTAUTH_SECRET=anyrandomsecuritytext
NEXTAUTH_URL=http://localhost:3000



11. Go to 'https://console.cloud.google.com/welcome'

12. Click in 'API and Services'

13. Setup OAuth consent screen if using for first time

14. Go to 'Credentials' and click 'CREATE CREDENTIALS' then select OAuth client ID

15. Select 'Web Application'

16. Then Enter Name and Add Authorised redirect URIs 'http://localhost:3000'

17. Add Authorised redirect URIs 'http://localhost:3000/api/auth/callback/google'

18. Save and copy GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET
and paste ito to env file

Now your NEXT JS AUTHENTICATION with PROTECTED ROUTES is ready with GOOGLE SIGNIN
 





Watch Next JS 14 Authentication | Protected Routes | Google SignIn in Next JS Using NextAuth Installation



Related Projects


Recent Comments

Latest Comments section by users