問題
LaravelでAPIを作っていて、後からSanctumでユーザー認証を導入しました。この結果、認証の必要なAPIと必要のないオープンなAPIがあります。この状況で検証環境に上げてブラウザーから認証の必要のないAPIへアクセスしたところ、突然CSRFエラーが出てアクセスできなくなりました。
実装したばかりの、認証の必要なAPIでエラーが出るならともかく、認証とは関係のないAPIでエラーが出るってどういうこと!?😯
原因
- Sanctumを導入する際に、APIに対してミドルウェアを仕込んだと思います。このミドルウェアが、ブラウザからのアクセスの場合のみCSRFトークンのチェックを行うミドルウェアを呼び出す処理を行っています。
- つまりブラウザからのアクセスの時は認証とは関係なく全APIにCSRFトークンのチェックが入ります。
対処法
二通り考えられて、ブラウザ→認証不要なAPIへのアクセスも、ちゃんとCSRFトークン仕込んで対策するというのが一つ。/csrf-cookieにアクセスして云々ってやつですね。
もう一つは割り切って、オープンなAPIに関してはCSRF対策の除外設定にしてしまう手もあります。APIの性質にもよりますが、CLIアクセス受け付けるのであれば、ブラウザ経由だけ取り締まってもしょうがない部分もあるので、妥当なケースもあるかと。
やり方はCSRF保護の項目に載っています。きっかけがSanctumなのでそっちを見がちですが、認証とCSRF保護は別物なので載ってません。注意。
通常、これらの種類のルートはroutes/web.phpファイル中で、App\Providers\RouteServiceProviderがすべてのルートへ適用するwebミドルウェアグループの外側に配置する必要があります。ただし、VerifyCsrfTokenミドルウェアの$exceptプロパティにURIを追加してルートを除外することもできます。
//
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* CSRF検証から除外するURI
*
* @var array
*/
protected $except = [
//ここにCSRFトークンの検証をしないAPIのURLを指定
];
}
これで解決!🎉
🙏Laravel公式ドキュメント翻訳者への支援のお願い
Laravelの公式ドキュメントの日本語版であるReaDouble.comを運営されている川瀬裕久氏が、広告収入の低下と持病の悪化のため、翻訳プロジェクトを継続することが困難になり、GitHub sponsorsを募集しています。 日本のLaravelユーザーでここを見たことない人はいないと思うので、もし恩義を感じているならば是非支援のほどお願いします。私も支援させていただいております