jwt authentication
Certainly! Let's build a fully functioning JWT authentication system in a Next.js application. This guide will provide a comprehensive overview of each step.
Set Up Your Next.js Project: Create a new Next.js project or use an existing one.
Install Dependencies: Install the required packages using npm or yarn:
npm install jsonwebtoken axios js-cookie
or
yarn add jsonwebtoken axios js-cookie
Create API Routes: In your
pages/api
directory, create API routes for handling authentication actions.pages/api/login.js
for handling user login:
import jwt from 'jsonwebtoken';
export default function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).end(); // Method Not Allowed
}
const { username, password } = req.body;
// Perform user authentication here (check username and password)
if (authenticated) {
const token = jwt.sign({ username }, 'secret_key', { expiresIn: '1h' });
res.status(200).json({ token });
} else {
res.status(401).json({ error: 'Authentication failed' });
}
}
pages/api/logout.js
for handling user logout:
export default function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).end(); // Method Not Allowed
}
// Clear token from cookies
res.clearCookie('token').status(200).json({ message: 'Logout successful' });
}
Create Components:
components/Layout.js
for consistent layout:
import React from 'react';
export default function Layout({ children }) {
return (
<div>
<header>Header</header>
{children}
<footer>Footer</footer>
</div>
);
}
components/LoginForm.js
for the login form:
import { useState } from 'react';
import axios from 'axios';
import Cookies from 'js-cookie';
export default function LoginForm() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async () => {
try {
const response = await axios.post('/api/login', { username, password });
const token = response.data.token;
Cookies.set('token', token);
window.location.href = '/protected'; // Redirect to protected route
} catch (error) {
console.error('Login failed:', error);
}
};
return (
<div>
<input type="text" value={username} onChange={(e) => setUsername(e.target.value)} />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
<button onClick={handleLogin}>Login</button>
</div>
);
}
Protected Route: Create a protected route using
getServerSideProps
to check if the user has a valid token before accessing the content.pages/protected.js
:
import Layout from '../components/Layout';
import jwt from 'jsonwebtoken';
import Cookies from 'js-cookie';
import { useRouter } from 'next/router';
export default function ProtectedPage() {
const router = useRouter();
return (
<Layout>
<h1>Protected Content</h1>
<button onClick={handleLogout}>Logout</button>
</Layout>
);
}
export async function getServerSideProps(context) {
const token = Cookies.get('token');
if (!token) {
return {
redirect: {
destination: '/login',
permanent: false,
},
};
}
try {
jwt.verify(token, 'secret_key');
return {
props: {},
};
} catch (error) {
return {
redirect: {
destination: '/login',
permanent: false,
},
};
}
}
Logout Functionality: Implement the logout functionality.
In
pages/protected.js
:function ProtectedPage() { const router = useRouter(); const handleLogout = async () => { try { await axios.post('/api/logout'); Cookies.remove('token'); router.push('/login'); } catch (error) { console.error('Logout failed:', error); } } return ( <Layout> <h1>Protected Content</h1> <button onClick={handleLogout}>Logout</button> </Layout> ); }
Final Steps:
Set up your CSS and styling according to your design.
Add links and navigation to your components as needed.
Make sure to handle errors and edge cases appropriately.
Consider token expiration and refresh logic for a production application.
Secure your JWT secret key and follow security best practices.
Remember that this example provides a basic JWT authentication system. In real-world applications, you should implement more advanced features such as token refresh, password hashing, error handling, and a more organized project structure.