認証認可 Next.js Laravel PHP サーバサイド セキュリティ フロントサイド

LaravelをAPIサーバとして運用するならSanctumにすべし

どうも、シローです。

今回はフロントサイドをNext.jsで実装し、LaravelをAPIサーバのみとして利用する場合、

認証部分はLaravel Sanctumを使うと良いよという内容です。

Laravel Sanctumとは

Laravel Sanctumはざっくりといえば、LaravelをAPIサーバとして運用する想定をサポートした認証システムです。

2つの機能があり

  • AuthorizationヘッダーにAPI Tokenを付与する
  • SPAで構築したフロントサイドとのアプリケーションをcookieベースの認証を行う

ことができます。

なので、クライアントアプリをモバイルアプリ、Next.jsのようなSPAで実装して、

データのやり取り部分はLaravelをAPIサーバとして利用するケース場合に利用するのが良いと思います。

SPAの認証について

クライアントサイドとサーバサイドを別々で実装する場合、

  • クライアントサイド:sample-service.com
  • サーバサイド:api.sample-service.com

のようにドメインが異なる場合があります。

この場合、XSSとかCSRFのようなセキュリティ的な対策のほか、CORSポリシーに引っかかるのでリクエストを正常に処理することが必要になってきます。

Laravel Sanctumでは、これらの対策をcookieを用いた認証機能でサポートしています。

 

初期設定(SPA認証をする場合)

  1. パッケージをインストール:composer require laravel/sanctum
  2. 設定ファイル(config/sanctum.php)を作成:php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
  3. API Tokenを保存するテーブルを作成:php artisan migrate
  4. apiルーティング(app/Http/Kernel.php)にSanctumのミドルウェアを使用するように設定

app/Http/Kernel.php

認証部分を実装

SanctumでAPIベースでユーザの認証を実装する例を紹介します。

設定ファイル(config/sanctum.php, config/cors.php, config/session.php)を編集

フロントサイドが別ドメインになっている場合、CORSポリシーによってリクエストが弾かれたりCookieが無効になるので設定ファイルを編集してやる必要があります。

今回は新規開発サービスを例として

  • フロントサイド:netaverse.local:3000
  • サーバサイド:api.netaverse.local

という設定で進めていきます。

config/cors.phpのstatefulにフロントサイドのドメインを追加する

.envにSANCTUM_STATEFUL_DOMAINSというキーにフロントサイドのドメイン(ポート番号を含む)の値を設定します。

.env

config/sanctum.phpのstatefulというキーに、この設定値を読み込むように設定します。

config/sanctum.php

config/cors.phpに許可するオリジンやリクエストメソッド、ヘッダーの設定をする

異なるドメインからのリクエストを許可するために、.envとconfig/cors.phpに次のような設定をいれます。

  • .envにフロントサイドのドメインをFRONT_SERVICE_HOSTというキーで設定
  • config/cors.phpを以下のように設定

.env

config/cors.php

config/session.phpにCookieを有効にするドメインを追加する

最後にCookieをサーバサイドで受け取ってユーザのセッション情報を取得できるようにconfig/session.phpのdomainというキーにトップドメインに「.」を追加したサブドメインを許容した値を設定します。

  • トップドメイン:netaverse.local
  • サブドメイン:api.netaverse.local

.env

config/session.php

 

フロントサイドのaxiosの設定

クロスオリジンでCookieベースのユーザ認証をするにはAccess-Control-Allow-Credentialsヘッダーにtrueを入れる必要があります。

また、CSRF保護を適用するためにsanctumが用意したエンドポイント(/sanctum/csrf-cookie)を事前に実行する必要があります。

.env

utils/axios.ts

api/csrfCookie.ts

ログイン部分の実装はこんな感じです

 

認証が必要なルーティングにミドルウェアを適用する

ユーザがログイン済みの場合のみにアクセスできるAPIを設計したい場合はミドルウェアのauth:sanctumを使用すると良いです。

auth:sanctumの中身はデフォルトのwebの認証ガードを使用した、Cookieベースのユーザ認証と同じになります。

routes/api.php

 

まとめ

  • SanctumはSPA認証時のクロスドメインの制約やCSRFやXSSといった対策をおこなってくれる
  • サーバサイドの設定方法はconfig/cors.php, config/sanctum.php, config/session.phpを編集するのみ
  • フロントサイドではリクエスト前に/sanctum/csrf-cookieを実行する必要あり
  • ユーザ認証のミドルウェアでauth:sanctumが使える

 

  • この記事を書いた人

シロー

Webシステムの開発のお仕事をさせて頂いております。 フリーランスの日常、Web開発に関する情報を発信しています。 趣味はゲーム、映画鑑賞、個人サービスを作ることです。

-認証認可, Next.js, Laravel, PHP, サーバサイド, セキュリティ, フロントサイド

© 2022 Shiro's secret base