概要

Next.jsを使ったセキュアな認証とセッション管理の一環として、JSON Web Tokens (JWT)クッキーを活用することは効果的です。クッキーにJWTを保存し、サーバー側でトークンを検証することで、クライアントとサーバー間のセッション管理がシンプルかつ安全に行えます。本記事では、JWTとクッキーを用いたセキュリティ強化の実装手法を紹介します。

JWTとクッキーの基礎

JWTは、ユーザー情報を暗号化し、トークンとして保存することで、セッションの状態をサーバー側で管理せずに認証を行う手法です。これにより、スケーラブルな認証システムが構築できます。

クッキーにJWTを安全に保存する

クライアント側のJavaScriptがアクセスできないHTTP-OnlyクッキーにJWTを保存することで、XSS(クロスサイトスクリプティング)攻撃から守ります。また、secure属性を使うことでHTTPS接続時のみクッキーが送信されるように設定します。

import { serialize } from 'cookie';
import jwt from 'jsonwebtoken';
export default function loginHandler(req, res) {
  const token = jwt.sign({ email: req.body.email }, process.env.JWT_SECRET, {
    expiresIn: '1h',
  });
  res.setHeader('Set-Cookie', serialize('authToken', token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    path: '/',
    maxAge: 3600, // 1時間
  }));
  res.status(200).json({ message: 'ログイン成功' });
}

この例では、JWTをHTTP-Onlyクッキーに保存し、セキュリティを強化しています。

ミドルウェアによるAPIルートの保護

APIルートを保護するために、JWTを検証するミドルウェアを使用します。JWTが存在しない場合や無効な場合は、リクエストを拒否し、認証されたユーザーのみがリソースにアクセスできるようにします。

import jwt from 'jsonwebtoken';
export const authMiddleware = (handler) => async (req, res) => {
  const token = req.cookies.authToken;
  if (!token) {
    return res.status(401).json({ message: 'Unauthorized' });
  }
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    return handler(req, res);
  } catch (error) {
    return res.status(401).json({ message: 'Invalid token' });
  }
};

このミドルウェアにより、保護されたAPIルートでのトークン検証が行われ、未認証のリクエストがブロックされます。

クッキー管理のベストプラクティス

  • httpOnly: クッキーがクライアント側のJavaScriptからアクセスできないように設定。
  • secure: HTTPS接続時のみクッキーが送信されるように設定。
  • sameSite: CSRF攻撃を防ぐために、クッキーの送信元を制限(例: strict)します。 これにより、クッキーの漏洩や攻撃のリスクを低減できます。

まとめ

Next.jsでのJWTとクッキーを活用した認証は、シンプルかつ効果的なセッション管理を提供します。HTTP-Onlyクッキーを使用してセキュリティを強化し、APIルートを保護するためにミドルウェアを導入することで、ユーザーのデータを守ることができます。これらのベストプラクティスを活用し、安全なWebアプリケーションを構築しましょう。