laravel8で作ったRestfulメモAPIにユーザ認証(laravel-breeze-api@sanctum)をつけてみた。postmanも良いけどcurlの方が一行で使い方を説明できて良い。
参照URL
https://github.com/nrikiji/laravel-breeze-api/blob/master/README.ja.md
BreezeをベースとしたAPIエンドポイントを簡単に実装するためのパッケージがあったので採用。v0.0.3ってのが気になるが…。
1 2 3 4 |
#パッケージのインストール composer require nrikiji/breeze-api # エラーになった。__DIR__ . "../../"みたいに相対パスになっていたので自分で修正したら上手く行った。 php artisan breeze-api:install |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// vendor/nrikiji/breeze-api/src/Console/InstallCommand.php:42 // Middleware... copy('/var/www/html/laravel/vendor/nrikiji/breeze-api/stubs/app/Http/Middleware/HandleAuthApiRequests.php', app_path('Http/Middleware/HandleApiAuthRequests.php')); // Providers... copy('/var/www/html/laravel/vendor/nrikiji/breeze-api/stubs/app/Providers/AuthServiceProvider.php', app_path('Providers/AuthServiceProvider.php')); // Tests... (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/tests/Feature', base_path('tests/Feature')); // Routes... copy('/var/www/html/laravel/vendor/nrikiji/breeze-api/stubs/routes/api.php', base_path('routes/api.php')); copy('/var/www/html/laravel/vendor/nrikiji/breeze-api/stubs/routes/auth.php', base_path('routes/auth.php')); |
1 2 3 4 |
#パッケージのインストール composer require laravel/sanctum # こっちもエラー。Authのコントローラーとミドルウェアがコピーされなかった…。しょうがないのでローカルでインストールしたのをコピーしたら動作した。 php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" |
app/Models/User.php
1 2 3 4 5 6 7 |
use Laravel\Sanctum\HasApiTokens; // 追加 class User extends Authenticatable { use HasApiTokens; // 追加 use HasFactory, Notifiable; } |
Sanctumとセッションを使用するためのミドルウェアをAPIに追加します
app/Http/Kernel.php
1 2 3 4 5 6 7 8 9 10 11 |
protected $middlewareGroups = [ 'api' => [ 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, # 以下3つを追加 \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \App\Http\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class, ], ]; |
routes/api.php
1 2 3 4 5 6 7 8 9 |
// laravel8から使うコントローラーのuseが必要 use App\Http\Controllers\MemoController; // 検索だけログインしなくても実行できる Route::get('/memo/search', [MemoController::class, 'search']); // 他のCRUD操作はログインが必要 Route::middleware('auth:sanctum')->group(function(){ Route::Resource('memo', MemoController::class); }); |
windows10のコマンドプロンプトで実行すればOK
ユーザ認証後のトークンIDは、自分でコピペする必要がある。
ユーザー作成(自動的にログイン状態)
1 2 |
curl -X POST -H "Accept: application/json" http://localhost/api/register -d "title=hoge" -d "email=hoge@example.com" -d "password=password" -d "password_confirmation=password" {{"token":"トークンIDが表示される"} |
ログイン
1 2 |
curl -X POST -H "Accept: application/json" http://localhost/api/login -d "email=hoge@example.com" -d "password=password" {"token":"トークンIDが表示される"} |
自分のユーザー情報を取得
1 |
curl -X GET -H "Accept: application/json" -H "Authorization: Bearer トークンID" http://localhost/api/user |
ログアウト
1 |
curl -X POST -H "Accept: application/json" -H "Authorization: Bearer トークンID" http://localhost/api/logout |
メモの全一覧(ログイン必要)
1 |
curl -X GET -H "Accept: application/json" -H "Authorization: Bearer トークンID" http://localhost/api/memo |
メモの登録(ログイン必要)
1 |
curl -X POST -H "Accept: application/json" -H "Authorization: Bearer トークンID" http://localhost/api/memo -d "title=hoge" -d "content=hoge_content" |
メモの登録(写真アップロード付)(ログイン必要)
1 |
curl -X POST -H "Accept: application/json" -H "Authorization: Bearer トークンID" http://localhost/api/memo -F "title=hoge" -F "content=hoge_content" -F "file=@C:\a.jpg" |
メモの更新(urlの最後にメモID指定)(ログイン必要)
1 |
curl -X PUT -H "Accept: application/json" -H "Authorization: Bearer トークンID" http://localhost/api/memo/1 -d "title=update_title" -d "content=update_content" |
メモの削除(urlの最後にメモID指定)(ログイン必要)
1 |
curl -X DELETE -H "Accept: application/json" -H "Authorization: Bearer トークンID" http://localhost/api/memo/1 |
メモの検索。検索だけログインしなくても実行できる
1 |
curl -X GET -H "Accept: application/json" http://localhost/api/memo/search?keyword=hoge |
localhostからajaxでlogin(post)しようとすると、419エラー(csrf token mismatch)になる~。
1 2 3 4 5 6 7 8 9 10 11 12 |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> $.ajax({ url: "https://apilaravel8.tk/api/login", type: "POST", headers: 'Accept: application/json', data: {"email":"hoge@example.com","password":"password"}, dataType:'json', success: function(response){ console.log(response); }, error: function(req, err){ console.log(req);console.log(err); } }); </script> |
APIはCSRFトークン対象外じゃないの!?と思ったら、SANCTUM認証のnrikiji/breeze-apiパッケージの実装に問題があったっぽい。
https://qiita.com/hikkappi/items/1b51b9e58e8e391762de
う~む。とりあえず、API関連だけcsrfトークンを無効化しておこう。apiによるユーザ認証は、どうするかな・・・。
app/Http/Middleware/VerifyCsrfToken.php
1 2 3 |
protected $except = [ '/api/*' ]; |