Authentication with NextJS and Next Auth
To implement **NextAuth.js** in a Next.js project for authentication, here’s a step-by-step guide:
### 1. Install Dependencies
You need to install the necessary packages:
npm install next-auth
### 2. Create the API Route
NextAuth.js uses API routes to handle authentication. Create a new file `pages/api/auth/[…nextauth].js`:
// pages/api/auth/[…nextauth].js
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
export default NextAuth({
providers: [
Providers.Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
// Add more providers here
],
pages: {
signIn: '/auth/signin',
},
});
- **Providers**: You can set up various OAuth providers like Google, Facebook, GitHub, etc. You need to register your app with the provider to obtain `clientId` and `clientSecret`.
### 3. Environment Variables
Set the environment variables for your OAuth providers in your `.env.local` file:
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
NEXTAUTH_URL=http://localhost:3000
### 4. Create a Sign-In Page
You can customize the sign-in page. Create a new file `pages/auth/signin.js`:
// pages/auth/signin.js
import { signIn } from 'next-auth/react';
export default function SignIn() {
return (
<div>
<h1>Sign In</h1>
<button onClick={() => signIn('google')}>Sign in with Google</button>
</div>
);
}
- **signIn(‘provider’)** triggers the sign-in flow for the provider you’ve set up, in this case, Google.
### 5. Protecting Pages
You can protect specific pages by wrapping your components with `getSession` or `useSession` to check if a user is authenticated.
For example, in a page component:
// pages/protected.js
import { getSession } from "next-auth/react";
export default function ProtectedPage() {
return (
<div>
<h1>This is a protected page</h1>
</div>
);
}
export async function getServerSideProps(context) {
const session = await getSession(context);
if (!session) {
return {
redirect: {
destination: '/auth/signin',
permanent: false,
},
};
}
return {
props: { session },
};
}
### 6. Accessing User Session
In any component, you can access the current session using `useSession`:
import { useSession } from 'next-auth/react';
export default function Navbar() {
const { data: session } = useSession();
return (
<nav>
{session ? (
<>
<p>Signed in as {session.user.name}</p>
<button onClick={() => signOut()}>Sign out</button>
</>
) : (
<button onClick={() => signIn()}>Sign in</button>
)}
</nav>
);
}
### 7. Handling Authentication States
You can handle loading and error states while checking session:
import { useSession } from "next-auth/react";
export default function Dashboard() {
const { data: session, status } = useSession();
if (status === "loading") return <div>Loading…</div>;
if (!session) return <div>Access Denied</div>;
return <div>Welcome {session.user.name}!</div>;
}
### 8. Customizing Callbacks and Session Behavior
You can customize callbacks and behavior for sessions, JWTs, and more in the NextAuth options:
/ pages/api/auth/[…nextauth].js
export default NextAuth({
providers: [
Providers.Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
],
callbacks: {
async session(session, token) {
session.user.id = token.sub;
return session;
},
async jwt(token, user) {
if (user) token.sub = user.id;
return token;
},
},
});
This way, you can attach additional user information to the session and JWT.
### 9. Testing Locally
1. Run the development server:
npm run dev
2. Go to `http://localhost:3000/auth/signin` to test the sign-in flow.
### 10. Deploying to Production
Make sure to set up environment variables for the production environment, such as `NEXTAUTH_URL` to the production domain.
### Conclusion
With these steps, you should have a basic NextAuth.js setup for handling authentication in a Next.js project. Depending on your needs, you can extend this further with more providers, database integration, or custom behaviors.