認証にまつわる物語

私はシステムデザインが大好きです。ユーザーにとって優れたソフトウェアを生み出すための、細かな意思決定について考えることが好きです。

エンジニアとして、私はセキュリティを重視しています。安全でなかったり、攻撃によって損失が発生したりするソフトウェアは、役に立ちません。私は、いつでも確実に動作する製品を作りたいと考えています。

最近、あるAIスタートアップの認証機能の開発に携わりました。フロントエンドにはNext.jsを使用しました。Next.jsはフロントエンドとバックエンドを一つのコードベースに統合できるため、小規模なチームにとって非常に強力です。

このプロジェクトでは、ブラウザ内で認証トークンをどのように保存し、保護するかという点に注力しました。その解決策は、クッキー、特にHttpOnlyクッキーです。

なぜLocal Storageではなくクッキーを使うのか?

Local Storageは使いやすいですが、リスクがあります。JavaScriptから読み取ることができてしまうため、クロスサイトスクリプティング(XSS)攻撃に対して脆弱になります。もし悪意のあるスクリプトがサイト上で実行されると、ユーザーのトークンが盗まれてしまう可能性があります。

クッキーはこの問題を解決します。クッキーにHttpOnlyフラグを付与することができるからです。これにより、ブラウザに対して「このクッキーはHTTPリクエスト経由でのみ送信すること。JavaScriptには触れさせないこと」と指示できます。

攻撃者がJavaScriptを使ってクッキーを読み取ろうとしても、何も見えません。クッキーは攻撃者からは見えない状態のままですが、ブラウザは自動的にサーバーへクッキーを送信し続けます。

クッキーをさらに安全にするために、私は他に2つのフラグを使用しています。

• Secure: クッキーがHTTPS経由でのみ送信されることを保証します。 • SameSite=Lax: クロスサイトリクエストフォージェリ(CSRF)攻撃を防ぐのに役立ちます。

Next.jsでの実装方法:

バックエンド(FastAPI)をブラウザから隠したいと考えました。そこで、Next.jsをプロキシとして使用し、サーバー間通信(server-to-server)の構成を作成しました。

  1. ユーザーがNext.jsのServer Action経由でログインします。
  2. Server Actionが認証情報をFastAPIに送信します。
  3. FastAPIがNext.jsサーバーにトークンを返します。
  4. Next.jsサーバーがそのトークンをHttpOnlyクッキーに書き込みます。
  5. ブラウザはクッキーを保存しますが、読み取ることはできません。

ユーザーがデータを必要とするとき、Next.jsサーバーがクッキーを読み取り、ユーザーに代わってバックエンドと通信します。機密性の高いトークンがブラウザのJavaScript環境に触れることはありません。

この構成により、バックエンドを隔離し、ユーザーの安全性を高めることができます。

あなたはNext.jsのプロジェクトで認証をどのように扱っていますか?ぜひ皆さんのアプローチを聞かせてください。

出典: https://dev.to/zikthemaker/an-auth-story-42hf