Orval でカスタム fetch を使って JWT トークンを付与したリクエストを送る
OpenAPI クライアントの自動生成ツール Orval と、カスタマイズした fetch 関数を組み合わせることで、JWTトークンを自動でリクエストヘッダーに含めるメモです。
この方法により、生成されたAPIクライアントを使う際に、認証情報を意識する必要がなくなります。ここでは、認証に Supabase を利用している例を元に解説します。
Orval で custom-fetch を扱う
まず、すべての AP Iリクエストに先立って Supabase** **から現在のセッショントークンを取得し、Authorization ヘッダーに設定するカスタム fetch 関数を作成します。
import { supabase } from "@/lib/supabase"; // Supabaseクライアントのインポート
export const customFetch = async <T>(
url: string,
options?: RequestInit,
): Promise<T> => {
// 1. Supabaseから現在のセッションを取得
const {
data: { session },
} = await supabase.auth.getSession();
// 2. 既存のヘッダーを複製
const headers = new Headers(options?.headers);
// 3. アクセストークンがあればAuthorizationヘッダーに設定
if (session?.access_token) {
headers.set("Authorization", `Bearer ${session.access_token}`);
}
// 4. APIのベースURLとリクエストURLを結合
const requestUrl = `${process.env.EXPO_PUBLIC_API_URL}${url}`;
// 5. APIリクエストを実行
const response = await fetch(requestUrl, {
...options,
headers, // トークン付きのヘッダーを適用
});
// 6. エラーハンドリング
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 7. レスポンスボディの処理 (204/205/304はボディなしとして処理)
const body = [204, 205, 304].includes(response.status)
? null
: await response.text();
const data = body ? JSON.parse(body) : {};
// 8. 必要な情報(データ、ステータス、ヘッダー)を返す
return {
data,
status: response.status,
headers: response.headers,
} as T;
};
ポイント
- セッション取得: supabase.auth.getSession()で現在のユーザーセッションを取得しています
- トークン挿入: session?.access_tokenが存在する場合に、Authorization: Bearer
形式でヘッダーに設定しています。これがJWTトークンをAPIに渡す標準的な方法です - ベースURL: process.env.EXPO_PUBLIC_API_URLを使ってAPIのベースURLを付加しており、Orvalが生成するクライアント側では相対パス(/usersなど)での指定が可能になります
Orval 設定ファイルでの mutator の指定
次に、Orvalの設定ファイルで、生成されるAPIクライアントが標準のfetchの代わりに、作成したcustomFetch関数を使用するように指定します。
import { defineConfig } from "orval";
export default defineConfig({
mobile: {
output: {
// ... その他の設定
client: "fetch", // fetchクライアントを使用することを指定
override: {
mutator: {
// customFetch関数へのパスと関数名を指定
path: "src/lib/custom-fetch.ts",
name: "customFetch",
},
},
},
input: {
target: "http://localhost:3001/doc", // OpenAPIドキュメントの場所
},
},
});
client: "fetch": Orval に、fetch ベースのクライアントを生成するよう指定します。
この方法により、アプリケーション全体で認証されたAPIリクエストを簡潔かつ安全に行えるようになります。
著者

hiro08gh (Hiroki Ueda)
フリーランスのフルサイクル / プロダクトエンジニア。プロダクト開発と犬が好き。Jamstack アーキテクチャーやサーバレス技術に興味があります。
Work Experience : MagicAl Pass、MONO Investment、microCMS、Commune...etc
SaaS 開発の経験が長く得意領域としています。業務において、ただ機能をリリースするだけではなく、「ユーザーが最大限使いやすいように考えること」、「長年使えるソフトウェアにすること」を大事にしています。
お仕事のお問い合わせは X (Twitter) の DM までお願いします。