En este tutorial aprenderas a crear un Login en Nextjs que permita a tus usuarios autenticarse en tu aplicación usando su cuenta de Google. Para esto usaremos NextAuthjs en conjunto con algunas caracteristicas nuevas de Nextjs como seria su carpeta App (App Router).
Creación de Proyecto de Nextjs
Primero creemos un proyecto de Nextjs:
npx create-next-app nextauth-google-tutorial
Estas son las configuraciones que usaré:
√ Would you like to use TypeScript? ... No / Yes
√ Would you like to use ESLint? ... No / Yes
√ Would you like to use Tailwind CSS? ... No / Yes
√ Would you like to use `src/` directory? ... No / Yes
√ Would you like to use App Router? (recommended) ... No / Yes
√ Would you like to customize the default import alias? ... No / Yes
Instalación de NextAuthjs
Luego instalaremos next-auth:
npm i next-auth
Crearemos un archivo en api/auth/[...nextauth]/route.ts:
import NextAuth from "next-auth/next";
import GoogleProvider from "next-auth/providers/google";
const handler = NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
],
});
export { handler as GET, handler as POST };
crea un archivo .env
Ahora pasaremos a crear un archivo .env en la raiz del proyecto y colocaremos un Client ID y un Client Secret de un proyecto de Google.
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
Estas credenciales las tenemos que crear primero desde un proyecto en Google Cloud Console. Para obtenerlos vamos a hacer los siguientes pasos:
- ve a la documentacion de Proveedor de Google en NextAuth o directamente a google cloud console
- Luego ve en Create Credentials (Puede que necesites crear un proyecto), y en OAUTH CLient ID, Luego en Application Type, escoge Web Application
- Te pedirea que crees un OAuth consent screen, coloca un nombre, y un correo de Developer Contact Information, luego continuar hasta el final, y listo.
- Nuevamente intentaremos entrar en Create Credentilas y seguir los mismos pasos. Entre los datos que coloqueremos estaran:
- Application type: web application
- Nombre
- Authorized JavaScript origins: http://localhost:3000, esto luego lo cambiaras en producción
- Authorized redirect URIs: http://localhost:3000/api/auth/callback/google
- Finalmente da un click en Create, y obtendras tu CLIENT_ID y tu CLIENT_SECRET
Creacion de Navegacion
Ahora vamos a crear una navegacion que nos permita ver la informacion del usuario que se ha autenticado, y tambien poder crear un boton para que cierre su sesion de usuario.
"use client";
import { signIn, useSession, signOut } from "next-auth/react";
import Link from "next/link";
function Navbar() {
const { data: session } = useSession();
return (
<nav className="flex justify-between px-40 mx-auto bg-slate-800 py-3">
<Link href="/">
<h1>NextGoogle</h1>
</Link>
{session?.user ? (
<div className="flex gap-x-2 items-center">
<Link href="/dashboard">Dashboard</Link>
<p>
{session?.user?.name} ({session?.user?.email})
</p>
<img
src={session?.user?.image as string}
alt="user"
className="w-10 h-10 rounded-full cursor-pointer"
onClick={() => signIn()}
/>
<button
onClick={() => {
signOut();
}}
>
Logout
</button>
</div>
) : (
<button onClick={() => signIn()}>Sign In</button>
)}
</nav>
);
}
export default Navbar;
Provider
Ahora que ya tenemos configurado nuestra navegacion, necesitamos crear un contexto para que todas las rutas puedan consultar los datos de un usuario.
Primero crearemos un archivo en app/Providers.tsx con el siguiente contenido:
"use client";
import { SessionProvider } from "next-auth/react";
export function Providers({ children }: { children: React.ReactNode }) {
return <SessionProvider>{children}</SessionProvider>;
}
Luego en Layout lo actualizaremos de esta forma:
import Navbar from "@/components/Navbar";
import { Providers } from "./Providers";
...
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<Providers>
<Navbar />
{children}
</Providers>
</body>
</html>
);
}
Proteccion de rutas con Middleware
Finalmente para proteger Rutas haremos uso del Middleware de NextAuth, crea un archivo middleware.ts con el siguiente contenido:
export { default } from "next-auth/middleware"
export const config = { matcher: ["/dashboard"] }
y una ruta app/dashboard/page.tsx con el siguiente contenido:
function DashboardPage() {
return <div>DashboardPage</div>;
}
export default DashboardPage;
Esto nos dara un error, ya que ahora necesita decifrar el contenido, asi que Aañade las variables de entorno de NextAUTH
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=QACep0YXFefAhWkPGZPBmVaPkolsPnGXBSLQq+Vo61Y=
Y con esto ya tendriamos un proyecto configurado con el Proveedor de Google en NextAuth.js