Laravel 10 入門トップページ


目次

  1. API とプロジェクトの概要
  2. プロジェクトの作成と初期設定
  3. データベースのマイグレーション
  4. シーダによるコメントデータの登録
  5. モデルの生成
  6. リソースの生成
  7. GETメソッドを利用した個別コメント取得のAPI作成
  8. 日本語文字列の表示と日時の調整
  9. GETメソッドを利用したコメント一覧取得のAPI作成
  10. データのラップ
  11. POSTメソッドを利用したコメントの新規投稿APIの作成
  12. PUTメソッドを利用したコメント更新APIの作成
  13. DELETEメソッドを利用したコメント削除APIの作成
  14. シーダの拡張
  15. ページネーションの実装
  16. 個別コメントをコントローラで取得
  17. Postman の利用
  18. ユーザ情報を登録する
  19. Sanctum によるユーザ認証
  20. ログインとトークン
  21. コメントとユーザのリレーションシップ
  22. 新規投稿時にユーザIDを記録する
  23. コメントからユーザ名を表示するリレーションシップ
  24. ユーザからコメント一覧を取得するリレーションシップ
  25. 更新と削除の権限設定
  26. 発行済みトークンの取得
  27. トークンの有効期限
  28. レート制限
  29. 閲覧権限の緩和

Laravel で API を開発する

レート制限

Laravel にはレート制限 (RateLimitter) の機能が実装されているので,短時間の間に大量のリクエストがあるとそのリクエストを遮断することができます.具体的には,1分間に60回を超えるリクエストがあると61回目からエラーを返します.実際に実験てみてください.

トークンの有効期限が設定されている状態であれば,まずトークンを再発行します.

C:\Users\Rinsaka>curl -X POST -d "email=a@sample.com" -d "password=abc" http://192.168.56.101:8000/api/login/ ⏎
{"user":{"id":1,"name":"A. Sample","email":"a@sample.com","email_verified_at":null,"created_at":"2023-11-02T15:01:01.000000Z","updated_at":"2023-11-02T15:01:01.000000Z"},"token":"7|lKDSUdk6bQ2kU6teYXHqfbsTtGEIOaPD6SxZ1GqB4b30e53c"}
C:\Users\Rinsaka>

今取得したトークンを使って次のコマンドを連続して短時間に送信します(ご自身で管理しているサーバに対して実験してください.他者が管理するサーバには決して実験しないようにしてください).

curl -H "Authorization: Bearer 7|lKDSUdk6bQ2kU6teYXHqfbsTtGEIOaPD6SxZ1GqB4b30e53c" http://192.168.56.101:8000/api/comments/5/

60回目までのリクエストに対しては望ましい結果が返却されましたが,61回目のリクエストに対しては「Too Many Requests」というエラーが表示されレート制限が適用されたことがわかります.

C:\Users\Rinsaka>curl -H "Authorization: Bearer 7|lKDSUdk6bQ2kU6teYXHqfbsTtGEIOaPD6SxZ1GqB4b30e53c" http://192.168.56.101:8000/api/comments/5/ ⏎ # 60回目
{"comment":{"id":5,"title":"松本 あすか","body":"8643910  長崎県西之園市西区石田町青田2-4-4 ハイツ井上103号 \/ yosuke68@example.net","owner":"B. Sample","updated_at":"2023-11-04T23:59:21.000000Z"}}
C:\Users\Rinsaka>curl -H "Authorization: Bearer 7|lKDSUdk6bQ2kU6teYXHqfbsTtGEIOaPD6SxZ1GqB4b30e53c" http://192.168.56.101:8000/api/comments/5/ ⏎ # 61回目
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Too Many Requests</title>

レート制限が適用されてもしばらく時間が経過するとまた同じユーザが接続できるようになります.

C:\Users\Rinsaka>curl -H "Authorization: Bearer 7|lKDSUdk6bQ2kU6teYXHqfbsTtGEIOaPD6SxZ1GqB4b30e53c" http://192.168.56.101:8000/api/comments/5/ ⏎
{"comment":{"id":5,"title":"松本 あすか","body":"8643910  長崎県西之園市西区石田町青田2-4-4 ハイツ井上103号 \/ yosuke68@example.net","owner":"B. Sample","updated_at":"2023-11-04T23:59:21.000000Z"}}
C:\Users\Rinsaka>

なお,レート制限は RouteServiceProvider.php において指定されています.このファイルを確認すると,ユーザ単位や送信元の IP アドレスで制限されることがわかります.

app/Providers/RouteServiceProvider.php<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * The path to your application's "home" route.
     *
     * Typically, users are redirected here after authentication.
     *
     * @var string
     */
    public const HOME = '/home';

    /**
     * Define your route model bindings, pattern filters, and other route configuration.
     */
    public function boot(): void
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });

        $this->routes(function () {
            Route::middleware('api')
                ->prefix('api')
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->group(base_path('routes/web.php'));
        });
    }
}

目次に戻る