1. Create a Login Form in Frontend (Next.js)
first need to create a login form in our frontend application. This will typically involve an HTML form or a React component.
import { useState } from ‘react’;
function LoginForm() {
const [email, setEmail] = useState(”);
const [password, setPassword] = useState(”);
const handleSubmit = async (event) => {
event.preventDefault();
const response = await fetch(‘/api/login’, {
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify({ email, password }),
});
const data = await response.json();
if (data.success) {
// Handle successful login, e.g., redirecting the user
} else {
// Handle login error
}
};
return (
<form onSubmit={handleSubmit}>
<input
type=”email”
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder=”Email”
/>
<input
type=”password”
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder=”Password”
/>
<button type=”submit”>Login</button>
</form>
);
}
export default LoginForm;
2. Create an API Route in Next.js
Next, create an API route in Next.js application to handle the form submission.
// pages/api/login.js
import { Payload } from ‘payload’;
export default async function handler(req, res) {
if (req.method === ‘POST’) {
const { email, password } = req.body;
try {
// Attempt to login with Payload’s authentication method
const result = await Payload.auth.login({
collection: ‘users’, // Replace with your user collection slug
data: {
email,
password,
},
});
res.status(200).json({ success: true, user: result.user, token: result.token });
} catch (error) {
res.status(401).json({ success: false, message: ‘Invalid credentials’ });
}
} else {
res.status(405).json({ message: ‘Method Not Allowed’ });
}
}
3. Configure Payload to Use JWT Authentication
Ensure that Payload is configured to use JWT for authentication. This is generally done in the payload.config.js file.
// payload.config.js
import { buildConfig } from ‘payload/config’;
export default buildConfig({
// Your Payload config options
collections: [
{
slug: ‘users’,
auth: true, // Enables authentication for this collection
fields: [
// User fields
],
},
],
// other config options
});
4. Handling the Authentication Response
Once the form is submitted and the API route is hit, the response should be handled on the frontend to either redirect the user or show an error message.
5. Redirect or Store JWT
On successful login, we may want to redirect the user to a dashboard or save the JWT token in local storage for later use in authenticated requests.
if (data.success) {
localStorage.setItem(‘token’, data.token);
window.location.href = ‘/dashboard’; // Redirect to a secure page
} else {
// Show an error message to the user
}
6. Protected Routes
For pages that require authentication, we should check if the JWT is present and valid before rendering the content.
// Example of a protected page
import { useEffect, useState } from ‘react’;
function Dashboard() {
const [user, setUser] = useState(null);
useEffect(() => {
const token = localStorage.getItem(‘token’);
if (!token) {
window.location.href = ‘/login’; // Redirect to login if not authenticated
} else {
// Fetch user data if needed
setUser({ … }); // Set the user data based on the token
}
}, []);
return (
<div>
<h1>Dashboard</h1>
{user && <p>Welcome, {user.name}</p>}
</div>
);
}
export default Dashboard;
Summary
- Frontend: Create a login form that posts to an API route.
- API Route: Handle the login logic using Payload’s authentication.
- JWT: Use JWT tokens to manage sessions and protect routes.