Laravel sanctumの認証を開発環境で通す時ハマったことメモ
概要
laravel+sanctumの認証をlocalhostの別portに立てたfrontendからfetchでアクセスし、
loginおよび認証を通した後のUser取得をやろうとしたが、ハマり散らかしたので備忘録としてまとめる
sanctomの設定と、corsの仕様の理解が必要だった
環境
php 8.1
laravel 9.21.6
laravel-sanctum 3.0.1
前提
基本的にsanctumの
公式documentの内容に準ずる。認証はApiTokenではなくsessionを使ったものを使う
公式documentではaxiosが例として出ていたが、XSRF-TOKENの取り扱いなどについて自分でやってみたかったのでfetchを使っている
バックエンドとフロントエンドはlocalhostで別々のportに動いている
ハマった箇所
XSRF-TOKENがcookieから取れない
axiosのwithCredentialsの設定は、fetchの場合credentialsで行う。以下のような指定がない場合Cookieが付与されない
fetch('url', { credentials: "include" })
devtool上ではcookieにTokenが入っているので、一見正しくリクエストできているように見えていたところでハマった
デフォルトではoriginをまたぐとcookieが送信されない
そのためlocalhost:5173(frontend) -> localhost:8000(backend) のような通信であっても、frontendではcredentialsの設定を、
バックエンドではAccess-Control-Allow-Credentialsの設定を行う必要がある
後者はsanctumのdocumentに言及がある通り、 cors.php でsupports_credentialsをtrueにすれば良い
Cookieから取得したXSRF-TOKENを設定しても認証を通らない
初歩的なミスで、URLデコードをかけていなかったのが原因。paddingに使っている=がエンコードされていた
SANCTUM_STATEFUL_DOMAINSを設定しているのに認証がこける
FRONTEND_URLは、http://localhost:5173のようにschemeから指定するが、
SANCTUM_STATEFUL_DOMAINSはlocalhost:5173のようにlocalhostとport番号の指定が必要だった
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful のmiddlewareにxdebugでブレークポイントを貼ったらfromFrontendが正しく判定を行えていなかったことが原因だとわかった
ちなみにこの他 SESSION_DOMAIN に誤ってport番号をつけたらcookieが取得できなくなったりした
Discussion