😸
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