guard.ts
serverモードだけで使えます。guard.tsで、ページを描画する前にリクエストを止めてログインのページへ送ったり、応答にヘッダーを足したりできます。
このページの内容
置き場所
src/routes/
guard.ts
layout.tsx
page.tsx
admin/
guard.ts
page.tsx
[id]/
page.tsxguard.tsはどの階層のディレクトリにも置けます。そのディレクトリより下のURLへのリクエストを処理する前に実行されます。URLに沿って複数あれば、外側から1つずつ順に実行されます。
この構成で/admin/42を開くと、ルートのguard.ts、admin/guard.tsの順に実行されます。どちらも通したときだけ、ページが描画されます。
戻り値
src/routes/admin/guard.tsimport { href } from '@k8ordo/framework';
import { cookies } from '@k8ordo/framework/server';
import type { Guard } from '@k8ordo/framework/server';
const guard: Guard<'/admin'> = () => {
if (cookies().has('session')) return;
何も返さないと、リクエストを通す
return new Response(null, {
`Response`を返すと、リクエストを打ち切る
status: 303,
headers: { location: href('/login') },
`href()`で作るとViteの`base`が付く
});
};
export default guard;Responseを返すと、それがそのまま応答になります。リダイレクトでも401でも403でも構いません。内側のguardもページも実行されません。
guardは{ request, params }を受け取ります。requestは受け取ったままのRequestです。paramsはそのディレクトリのパターンのパラメータで、値はスキーマで変換される前のURLの文字列です。
型は@k8ordo/framework/serverのGuardです。型引数には、そのディレクトリのパターンを渡します。生成されたルート表も、それぞれのguard.tsをディレクトリのパターンで検査します。
メモ
Responseでもundefinedでもない値を返すと、エラーになります。エラー文はa guard.ts returns a Response to end the request, or nothing to let it throughです。
応答のヘッダー
src/routes/guard.tsimport { responseHeaders } from '@k8ordo/framework/server';
export default function guard() {
responseHeaders().set('x-content-type-options', 'nosniff');
}responseHeaders()は、最終的な応答に付くHeadersを返します。リクエストを通したときも、このHeadersに足したヘッダーは応答に付きます。ページでもペイロードでも、not-foundでも、内側のguardが返したResponseでも同じです。同じ名前のヘッダーがすでにあれば、この値に置き換わります。
responseHeaders()を呼べるのは、guard.tsとroute.tsとServer Actionの中だけです。ページの描画中に呼ぶと、responseHeaders() belongs to what answers the requestで始まるエラーになります。リクエストの外で呼ぶと、responseHeaders() needs a requestで始まるエラーになります。
Content-Security-Policyのヘッダーも、ルートのguard.tsで書きます。書き方はCSPを見てください。
描画後の書き換え
ページを実行して応答を受け取り、書き換えてから返すnext()はありません。ページはストリーミングで返るので、本文を書き終える前にヘッダーが送られます。guardが決められるのは、ページの描画が始まる前だけです。
対象のリクエスト
そのディレクトリより下にある、次のリクエストが対象です。
- ページと、クライアント側の遷移で取得するそのペイロード
- そのページへの
HEAD - そのページへ送られたServer Action
- 下にある
route.tsとnot-found.tsx
ルートのguard.tsは、どのルートにも当たらなかったURLでも実行されます。
メモ
guardが守るのは、Server Actionそのものではありません。アクションはどのページからでも呼べる関数で、呼んだページのURLへ送られます。アクションに必要な確認は、アクションの中でも行ってください。
実行の順序
guardは、paramsSchemaがURLを照合したあと、Server Actionと描画の前に実行されます。redirect.tsはどのguardよりも先に応答を返します。[locale]の下のguardでは、URLが示すロケールがすでに決まっています。guardが書いたCookieは、そのあとのServer Actionで読めます。