😸

Next.jsのmiddlewareでhash関数を使いたい

に公開

前提としてNext.jsのmiddlewareではNode.jsランタイムが動かない。そのためNode.js標準ライブラリのcryptoモジュールを使おうとすると500エラーとなる

// 500エラー
import { createHash } from "crypto";

グローバルなcryptoオブジェクトを使うとWeb標準のWeb Crypto APIを参照する、これは正常に動作する

// これは動く
const hashBuffer = await crypto.subtle.digest("SHA-256", data);

Next.jsはコードによって動く場所が決まるため、以下のようなファイルを用意しておくとサーバー・クライアント・エッジに対応したhash化の関数を揃えることができる

import { createHash } from "crypto";

// Web Crypto APIを使用するハッシュ関数(Edge Runtimeで使用可能)
export const toHashEdge = async (str: string) => {
  const encoder = new TextEncoder();
  const data = encoder.encode(str);
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
};

// クライアント用(React コンポーネントで使用)
export const toHashClient = async (str: string) => {
  "use client";
  return await toHashEdge(str);
};

// サーバー用(Node.js環境で使用)
export const toHashServer = (str: string) => {
  return createHash("sha256").update(str).digest("hex");
};

middleware.ts では toHashEdge() を使う

株式会社エス・エム・エス

Discussion