Get a Pentest and security assessment of your IT network.

Cyber Security

Next.js Authentication: Long Sessions

TL;DR

This guide shows how to handle user authentication in a Next.js application with Server-Side Rendering (SSR) and long session durations. We’ll use cookies for storing session tokens, focusing on security best practices.

1. Choose an Authentication Method

Several options exist: NextAuth.js is popular, but we’ll focus on a simpler approach using JSON Web Tokens (JWTs) and cookies directly for clarity. This assumes you have a backend API to handle user registration/login.

2. Backend API Setup

Your backend needs endpoints for:

  • Registration: Creates new users.
  • Login: Authenticates users and returns a JWT upon success.

Example (Node.js/Express with jsonwebtoken):

const jwt = require('jsonwebtoken');

app.post('/login', async (req, res) => {
  // ... authentication logic...
  if (userIsValid) {
    const token = jwt.sign({ userId: user._id }, 'your-secret-key', { expiresIn: '7d' }); // 7 day expiry
    res.cookie('authToken', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'strict' });
    res.json({ message: 'Login successful' });
  } else {
    res.status(401).json({ message: 'Invalid credentials' });
  }
});

Important: Replace 'your-secret-key' with a strong, randomly generated secret.

3. Setting Cookies on Login

When the user successfully logs in via your backend API, set an HTTP-only, secure cookie containing the JWT:

  • httpOnly: true: Prevents client-side JavaScript from accessing the cookie (protects against XSS attacks).
  • secure: process.env.NODE_ENV === 'production': Only send the cookie over HTTPS in production environments.
  • sameSite: 'strict': Helps prevent CSRF attacks by only sending the cookie with requests originating from your domain.

4. Reading Cookies on the Server (SSR)

In Next.js, use getServerSideProps to access cookies during SSR:

export async function getServerSideProps(context) {
  const { req } = context;
  let authToken = req.cookies.authToken;

  if (authToken) {
    try {
      const decodedToken = jwt.verify(authToken, 'your-secret-key');
      // User is authenticated...
      return { props: { user: decodedToken } };
    } catch (error) {
      // Token is invalid or expired...
      console.log('Invalid token:', error);
    }
  }

  return { props: { user: null } }; // User not authenticated
}

Important: Use the same secret key as your backend API.

5. Client-Side Authentication (SPA)

For client-side routes, you can check for the cookie using document.cookie:

function getAuthToken() {
  const cookies = document.cookie.split(';');
  for (let i = 0; i < cookies.length; i++) {
    const cookie = cookies[i].trim();
    if (cookie.startsWith('authToken=')) {
      return cookie.substring('authToken='.length, cookie.length);
    }
  }
  return null;
}

Use this function to determine if the user is logged in and redirect them accordingly.

6. Protecting Routes

Create a custom component or higher-order component (HOC) to protect routes:

  • Server-Side: Use getServerSideProps to check the cookie and return a redirect if the user is not authenticated.
  • Client-Side: Check for the cookie before rendering the route. If it's missing, redirect the user to the login page.

7. Session Renewal

To extend session duration without requiring a full re-login:

  • Implement an API endpoint that issues a new JWT when provided with a valid (but potentially expiring) existing token.
  • Periodically refresh the cookie on the client-side using this endpoint (e.g., every hour).

8. Security Considerations

  • Strong Secret Key: Use a long, randomly generated secret key for JWT signing. Store it securely (environment variables are recommended).
  • HTTPS: Always use HTTPS in production to protect cookies from interception.
  • HTTP-Only Cookies: Prevent client-side JavaScript access to session cookies.
  • SameSite Attribute: Mitigate CSRF attacks.
  • Token Expiration: Set appropriate token expiration times (balance security and user experience).
  • Refresh Tokens (Advanced): Consider using refresh tokens for improved security and a better user experience.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation