@duongtrungnguyen/next-helper
v0.1.8
Published
Helper library for Next.js 15
Maintainers
Readme
Next.js JWT Authentication Library Documentation
Table of Contents
Introduction
This authentication library provides a complete solution for JWT-based authentication in Next.js applications. It supports both client and server components, handles token refresh automatically, and provides utilities for making authenticated API requests.
Key Features
- JWT Authentication: Secure authentication using JSON Web Tokens
- Automatic Token Refresh: Seamless refresh of expired tokens
- App Router Support: Full compatibility with Next.js App Router
- TypeScript Support: Complete type definitions for all components
- Server Components: Authentication utilities for React Server Components
- Middleware Integration: Route protection at the middleware level
- HTTP Utilities: Simplified authenticated API requests
Installation
- Configure environment variables in your
.env.localfile:
# Auth API Configuration
NEXT_PUBLIC_API_BASE_URL= # default is: http://localhost:3001
NEXT_PUBLIC_AUTH_GLOBAL_PREFIX= # default is: ""
NEXT_PUBLIC_LOGIN_ENDPOINT= # default is: /sign-in
NEXT_PUBLIC_LOGOUT_ENDPOINT= # default is: /sign-out
NEXT_PUBLIC_REFRESH_TOKEN_PREFIX= # default is: /refresh
NEXT_PUBLIC_USER_ENDPOINT= # default is: /user
NEXT_PUBLIC_ACCESS_TOKEN_PREFIX= # default is:auth.access-token
NEXT_PUBLIC_REFRESH_TOKEN_PREFIX= # default is:auth.refresh-token
NEXT_PUBLIC_AUTH_TOKEN_TYPE= # default is:Bearer- Initialize the authentication system in your root layout:
// app/layout.tsx
import { AuthProvider } from "@duongtrungnguyen/next-helper";
import "./globals.css";
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<AuthProvider>{children}</AuthProvider>
</body>
</html>
);
}Core Concepts
Authentication Flow
- Login: User provides credentials → Server validates and returns JWT tokens → Client stores tokens in cookies
- API Requests: Client retrieves token from cookies → Sends in Authorization header → Server validates token
- Token Refresh: When access token expires → Client sends refresh token → Server issues new tokens → Client updates cookies
- Logout: Client clears tokens from cookies
Token Storage
Tokens are stored in HTTP-only cookies for security, but are sent in the Authorization header for API requests. This approach:
- Protects tokens from XSS attacks (HTTP-only cookies)
- Follows standard API authentication practices (Authorization header)
- Maintains compatibility with backend services expecting tokens in headers
Authentication Context
The library provides a React context that exposes:
- Current authentication state (user, loading, error)
- Authentication methods (login, logout, refreshTokens)
- Token management utilities
Configuration
The library can be configured through environment variables or by passing a configuration object to the initAuth function.
API Reference
Client-Side API
useAuth()
React hook that provides access to the authentication context.
Returns:
{
state: {
user: User | null; // Current user or null if not authenticated
isLoading: boolean; // True when authentication state is loading
isAuthenticated: boolean; // True when user is authenticated
error: string | null; // Error message or null
};
login: (credentials: LoginCredentials) => Promise<void>; // Login function
logout: () => Promise<void>; // Logout function
refreshTokens: () => Promise<boolean>; // Refresh tokens function
}Example:
"use client";
import { useAuth } from "@duongtrungnguyen/next-helper";
export default function LoginForm() {
const { login, state } = useAuth();
const handleSubmit = async (e) => {
e.preventDefault();
await login({
email: "[email protected]",
password: "password"
});
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
<button type="submit" disabled={state.isLoading}>
{state.isLoading ? "Logging in..." : "Login"}
</button>
{state.error && <p>{state.error}</p>}
</form>
);
}useProtectedRoute()
React hook that redirects to the login page if the user is not authenticated.
Returns:
{
isLoading: boolean; // True when authentication state is loading
isAuthenticated: boolean; // True when user is authenticated
}Example:
"use client";
import { useProtectedRoute } from "@duongtrungnguyen/next-prepare";
export default function ProfilePage() {
const { isLoading } = useProtectedRoute();
if (isLoading) {
return <div>Loading...</div>;
}
return <div>Profile content (only visible to authenticated users)</div>;
}AuthProvider
React context provider that must wrap your application.
Props:
{ children: ReactNode; // Child components }Server-Side API
getCurrentUser()
Server action that retrieves the current user based on the access token in cookies.
Returns:
Promise<User | null> // User object or null if not authenticatedExample:
// app/profile/page.tsx
import { getCurrentUser } from "@duongtrungnguyen/next-prepare";
export default async function ProfilePage() {
const user = await getCurrentUser();
if (!user) {
return <div>Please log in to view your profile</div>;
}
return (
<div>
<h1>Welcome, {user.name}</h1>
<p>Email: {user.email}</p>
</div>
);
}setAuthCookies(tokens: AuthTokens)
Server action that sets authentication cookies for access and refresh tokens.
Parameters:
tokens: Object containingaccessTokenandrefreshToken
Example:
import { setAuthCookies } from "@duongtrungnguyen/next-prepare";
// Example usage in a custom login API route
export async function POST(request: Request) {
const { email, password } = await request.json();
// Authenticate user (implementation depends on your backend)
const tokens = await authenticateUser(email, password);
if (tokens) {
await setAuthCookies(tokens);
return Response.json({ success: true });
}
return Response.json({ success: false }, { status: 401 });
}clearAuthCookies()
Server action that clears authentication cookies.
Example:
import { clearAuthCookies } from "@duongtrungnguyen/next-prepare";
// Example usage in a custom logout API route
export async function POST() {
await clearAuthCookies();
return Response.json({ success: true });
}refreshAccessToken()
Server action that refreshes the access token using the refresh token in cookies.
Returns:
Promise<boolean> // True if token was successfully refreshedMiddleware
authMiddleware(request: NextRequest)
Middleware function that checks if the access token is about to expire and refreshes it if necessary.
Parameters:
request: Next.js request object
Returns:
Promise<NextResponse> // Next.js response object
Example:
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { authMiddleware } from "@duongtrungnguyen/next-prepare";
export async function middleware(request: NextRequest) {
return await authMiddleware(request);
}
export const config = {
matcher: [
"/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
],
};HTTP Utilities
HttpClient
Universal fetch utility class that works in both client and server components.
Methods:
get<T>(url: string, config?: RequestConfigs): Promise<T>post<T>(url: string, data?: any, config?: RequestConfigs): Promise<T>put<T>(url: string, data?: any, config?: RequestConfigs): Promise<T>delete<T>(url: string, config?: RequestConfigs): Promise<T>
Example:
import { httpClient } from "@duongtrungnguyen/next-prepare";
// In any component (client or server)
const fetchData = async () => {
try {
const data = await httpClient.get("/api/protected-resource");
return data;
} catch (error) {
console.error("Error fetching data:", error);
}
};