Server Actions と Cookie 認証 - フォーム送信時に何が起きるか

中級 | 9分 で読める | 2026.06.14

公式ドキュメント

Server Actions とは

Server Actions は、Next.js App Routerでサーバ側関数として更新処理を書ける機能です。

フォーム送信やデータ更新を、サーバ側の関数に直接つなげるような書き方ができます。

"use server";

export async function createPost(formData: FormData) {
  const title = String(formData.get("title"));
  await db.post.create({ data: { title } });
}

認証付きアプリでは、この関数の中で必ずsessionを確認します。

ブラウザがログイン済みで、HttpOnly Cookie にセッションIDを持っているとします。

Cookie: session_id=abc123

ユーザーがフォームを送信すると、ブラウザはNext.jsサーバへリクエストを送ります。このとき、条件に合うCookieが自動で付与されます。

Server Action側では、そのCookieをもとにsessionを確認できます。

"use server";

import { auth } from "@/auth";

export async function createOrder(formData: FormData) {
  const session = await auth();
  if (!session) {
    throw new Error("Unauthorized");
  }

  await createOrderForUser(session.user.id, {
    title: String(formData.get("title")),
  });
}

access token はサーバ側で使う

外部APIを呼ぶ必要がある場合も、access tokenはサーバ側で取り出して使います。

"use server";

import { auth } from "@/auth";
import { getAccessToken } from "@/lib/server/access-token";

export async function createOrder(formData: FormData) {
  const session = await auth();
  if (!session) throw new Error("Unauthorized");

  const accessToken = await getAccessToken();

  const res = await fetch("https://api.example.com/orders", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: String(formData.get("title")),
    }),
  });

  if (!res.ok) throw new Error("Failed to create order");
}

この accessToken はブラウザに返しません。Server Actionの関数内だけで使います。

戻り値に秘密を含めない

Server Actionの戻り値は、クライアント側で受け取れる場合があります。

そのため、戻り値にaccess token、refresh token、秘密情報を含めてはいけません。

// 悪い例
return {
  ok: true,
  accessToken,
};

返すのは、UI表示に必要な最小限の情報だけにします。

return {
  ok: true,
  message: "作成しました",
};

注意: Server Action はサーバで実行されますが、戻り値やClient Componentへ渡した値はブラウザ側に出る可能性があります。秘密を返さないことが重要です。

CSRF 対策も考える

Cookie認証では、Cookieが自動送信されます。そのため、CSRF対策も必要です。

Next.jsや認証ライブラリの仕組みに任せられる部分もありますが、設計としては次を意識します。

  • 状態変更はGETで行わない
  • SameSite Cookie を適切に設定する
  • 必要に応じてCSRFトークンを使う
  • Origin / Referer 検証を検討する
  • 重要操作では再認証を求める

Server ActionsだからCSRFを考えなくてよい、ではありません。

認可チェックを省略しない

ログイン済みかどうかだけでなく、その操作をしてよいユーザーかも確認します。

const order = await db.order.findUnique({
  where: { id: orderId },
});

if (!order || order.userId !== session.user.id) {
  throw new Error("Forbidden");
}

認証は「誰か」を確認すること、認可は「その操作をしてよいか」を確認することです。

まとめ

Server Actionsでは、フォーム送信や更新処理をサーバ側に置けます。

  • ブラウザはCookie付きでNext.jsへリクエストする
  • Server Action内でsessionを確認する
  • access tokenはサーバ側で使い、ブラウザに返さない
  • 戻り値に秘密を含めない
  • CSRF対策を考える
  • 認証だけでなく認可も確認する

参考リソース

  • 公式ドキュメント - Server Actions と Cookie 認証 - フォーム送信時に何が起きるか を確認するための一次情報

次に読む記事

← 一覧に戻る
PR
PR
PR
PR