こんにちは。よっしーです(^^)
今日は、SvelteKitでのstate管理について解説しています。
背景
SvelteKitでのstate管理について調査する機会がありましたので、その時の内容を備忘として記事に残しました。
SvelteKitでのstate管理について
クライアントのみのアプリの構築に慣れている場合、サーバーとクライアントにまたがるアプリでの状態(state)管理は困難に思えるかもしれません。このセクションでは、よくある落とし穴を回避するためのヒントを紹介します。
サーバー上での状態の共有を避ける
ブラウザはステートフルです – ユーザーがアプリケーションを操作する際、状態がメモリに保存されます。一方、サーバーはステートレスです – レスポンスの内容は、リクエストの内容によって完全に決定されます。
これは概念的な話です。実際には、サーバーは長期間稼働し、複数のユーザーによって共有されることがよくあります。そのため、共有変数にデータを保存しないことが重要です。例えば、次のようなコードを考えてみましょう:
// +page.server.js
let user;
/** @type {import('./$types').PageServerLoad} */
export function load() {
return { user };
}
/** @type {import('./$types').Actions} */
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
// NEVER DO THIS!
user = {
name: data.get('name'),
embarrassingSecret: data.get('secret')
};
}
}
user
変数は、このサーバーに接続するすべての人によって共有されます。もしアリスが恥ずかしい秘密を送信し、その後ボブがページを訪れた場合、ボブはアリスの秘密を知ることになってしまいます。さらに、アリスが後日サイトに戻ってきたとき、サーバーが再起動されていて彼女のデータが失われている可能性があります。
代わりに、cookies
を使用してユーザーを認証し、データをデータベースに永続化するべきです。
解説
このコードは、SvelteKitアプリケーションのサーバーサイドの一部を示しています。しかし、このコードには重大な問題があります。以下に詳細を説明します:
- グローバル変数の使用:
let user;
このグローバル変数 user
は、すべてのリクエストで共有されます。これは先ほど説明した問題の原因となります。
load
関数:
export function load() {
return { user };
}
この関数は、ページロード時に実行され、user
変数の内容を返します。しかし、これはグローバル変数を使用しているため、セキュリティとプライバシーの問題があります。
actions
オブジェクト:
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
// NEVER DO THIS!
user = {
name: data.get('name'),
embarrassingSecret: data.get('secret')
};
}
}
この部分は特に問題があります:
- フォームデータを直接グローバル変数に保存しています。
- ユーザーの機密情報(’embarrassingSecret’)を安全でない方法で扱っています。
- コメントにも “NEVER DO THIS!”(決してこのようなことをしないでください!)と書かれています。
このコードの問題点:
- セキュリティ:ユーザーの秘密が他のユーザーに見える可能性があります。
- プライバシー:個人情報が適切に保護されていません。
- データの永続性:サーバーが再起動するとデータが失われます。
- スケーラビリティ:複数のサーバーインスタンスがある場合、データの整合性が保てません。
改善方法:
- セッション管理を使用する(例:cookieベースの認証)
- ユーザーデータをデータベースに保存する
- 適切な認証と認可のメカニズムを実装する
- 機密情報を暗号化して保存する
このコードは、「どのようにコードを書くべきでないか」を示す例として使用されているようです。実際のアプリケーションでは、このようなアプローチは避けるべきです。
おわりに
今日は、 SvelteKitでのstate管理について解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント