eyecatch

SvelteKitアプリで突然ログアウトされる理由はこれだった

Posted on 2024/12/04
# Technology

Introduction

SvelteKit を使用して Web アプリケーションを作成していました。SvelteKit は記述量が少なく、個人的には React + Next よりも気に入っているフレームワークです。
しかし、ランダムなタイミングで cookies 内に保存されている login token が勝手に削除される事象が発生しました。
この問題の原因が数日間わからず苦労しましたが、最近やっと解決したので、その記録としてブログに残します。

TL;DR

・Logout リンクを hover するとログアウトされてしまう問題が発生しました。
・原因は、<a> にデフォルトで設定されている data-sveltekit-preload-data="hover" の挙動でした。
・この問題は、data-sveltekit-preload-data="off" に設定することで解決しました。
・GETリクエストは副作用を伴わせない為 POSTリクエストを使用しましょう。

Logoutリンクの上をカーソールが通るとLogoutされる

この問題が発生するタイミングは、Logout リンク上をカーソルが通過したときでした。
通常、Logout リンクをクリックすると cookies 内の auth token が削除されてログアウトされます。

原因は SvelteKit の機能である data-sveltekit-preload-data が原因でした。

data-sveltekit-preload-data について

data-sveltekit-preload-data は SvelteKit が提供しているLink Option という機能です。
<a> にはdata-sveltekit-preload-data='hover' がデフォルトで設定されており、リンクが hover されたタイミングで click イベントを予測します。
このタイミングで事前に code と必要であれば page data を取得し、クリックがされたタイミングで素早くページ遷移してくれる嬉しい機能です。

設定値として hovertap があり、必要に応じて変更または無効にすることができます。
また他にも data-sveltekit-preload-codedata-sveltekit-reload など色々あります。

何が起きていたのか

Logout リンクは data-sveltekit-preload-data='hover' がデフォルトでされてました。
hover とタイミングで GET /logout にリクエストが飛びます(ページの遷移はされない)。
GET /logout の load function の中ではトークンを削除するロジックがあるので、hover のタイミングでこの処理がされてしまっているのが原因でした。

ログなども表示されなくデバッグもできなく解決に長い時間を消費しました。。。

解決策

<a data-sveltekit-preload-data='tap' /> または<a data-sveltekit-preload-data='off' /> でホバーでの発火を防ぐことができます。

また GETリクエストは副作用を伴わせないようにした方が良く、Logoutには POSTリクエストを使うのがより適切そうです。

まとめ

ランダムなタイミングで何かの処理が実行されるようであれば一度 data-sveltekit-preload-data の処理を確認してみると良いです。
もし Logout に GET を使用してるのであれば POSTリクエストで処理する方法がより適切です。