Server Actions はクライアントに公開されている!?
先日、Next.jsのブログを読んでいたら、「Server Actionsの中でもバリデーションしてね」とあったので、注意喚起も兼ねて、その紹介ですmm
Server Actionsってなんやねんって方は、公式による説明か以下の記事がわかりやすかったので、まずはそちらからmm
Server Actions はクライアントに公開されている!?
ServerActionsで定義したすべての関数はエンドポイントが公開され、ユーザーは直接、エンドポイントから関数を実行できる状態になっています。
エンドポイントは特定されないように、ソースコードの場所をハッシュ化した値をもとに作成されているので、簡単にバレにくいようにはなってるっぽいです。
( !! ここの理解は曖昧なので、詳しい方いたら、教えてください 🙇♂️ !! )
Server Actions の中でもバリデーションをかけよう
ということで、 「フロント側でバリデーションしてるから、server actionsは任意の処理を実行するだけで良いよね〜」 はよくない!:no_good_tone1:
Server Actions の中でも、引数が適切な値なのか確認しましょう!:muscle:
公式が出してる例では、以下のようにidがnumber型か確かめています。TypeScriptで実装していても、実行される段階ではJavaScriptにトランスパイルされているので、型も確認しようねってことだと思います。
"use server";
export async function deletePost(id: number) {
if (typeof id !== 'number') {
throw new Error();
}
const user = await getCurrentUser();
if (!canDeletePost(user, id)) {
throw new Error();
}
...
}
他にもありそうな例でいうと、ユーザーが処理を実行して良いユーザーかを認可するケース
"use server";
export async function updateAccount(data: hoge) {
try {
const user = await getCurrentUser()
await updatedAccountGueard(user, data);
await update();
} catch (error) {
throw Error()
}
}
公式さんも以下のように言っていますので、Server Actions を使う際は、ちゃんと値を検証しましょうね。
The principle is that the argument list to Server Actions ("use server") must always be treated as hostile and the input has to be verified.
(↓翻訳 by DeepL↓)
原則としては、サーバーアクション("use server")の引数リストは常に敵対的なものとして扱われ、入力は検証されなければならない。
Discussion