🥵

Laravel sanctumの認証を開発環境で通す時ハマったことメモ

2022/08/12に公開

概要

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