メインコンテンツまでスキップ

Laravel API サーバー構築準備

このコースでは、CRUD アプリコースとは違い、Laravel を API サーバーとして実装することになるため、必要な準備を行いましょう。

プロジェクトの作成

Laravel プロジェクト作成に沿って、プロジェクトを作成してください。

ルーティングの設定

API サーバーとしてのルーティングを設定します。以下のコマンドを実行して、api.phpファイルを作成します。

sail artisan install:api

途中でマイグレーションを行うかどうか聞かれるので、yesを入力してください。

次に、routes/api.phpに以下のコードを追加してください。

routes/api.php
Route::get('/sample', function () {
return response()->json(['message' => 'Hello World!']);
});

sail up -dでサーバを立ち上げ、http://localhost/api/sample にアクセスすると、{"message":"Hello World!"}と表示されることが確認できます。

api.phpで定義したルートには、自動でapiのプレフィックスが付与されることに注意してください。

最後にユーザー関連のテーブルのマイグレーションが必要なので、以下のコマンドを実行してください。

sail artisan migrate

認証の設定

CURD コースでは、Laravel Breezeを使って認証機能を実装しましたが、API サーバーではLaravel Sanctumというパッケージを使って認証機能を実装します。sail artisan install:apiコマンドを実行した時点で、Laravel Sanctumがインストールされています。

それでは、新規登録とログインのためのエンドポイントを作成しましょう。まずは、以下のコマンドを実行してコントローラーを作成します。

sail artisan make:controller Auth/RegisterController --invokable
sail artisan make:controller Auth/LoginController --invokable

次に、routes/api.phpに以下のコードを追加してください。

routes/api.php
use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\Auth\LoginController;

// 省略

Route::post('/register', RegisterController::class);
Route::post('/login', LoginController::class);

ユーザー登録処理

app/Http/Controllers/Auth/RegisterController.phpにユーザー登録の処理を追加しましょう。

app/Http/Controllers/Auth/RegisterController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class RegisterController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8',
]);

$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);

return response()->json(['user' => $user]);
}
}

postman の利用

試しにリクエストを送りたいのですが、画面が存在しないのでどうすればいいでしょうか。

API サーバー開発においては、フロントエンドの画面が出来るまではpostmanというツールを使ってリクエストを送り、動作確認をすることが多いです。

postman のダウンロードページにアクセスし、ダウンロードとインストールを行ってください。

インストールが完了したら、postman を起動します。起動すると以下のような画面が表示されます。

alt text

ここで、メソッドや URL、リクエストパラメータなどを設定してリクエストを送信することができます。 それでは実際に http://localhost/api/register にリクエストを送ってみましょう。

以下の画像を参考に設定してください。

alt text

JSON はこちらの内容を入力してください。

{
"name": "テスト太郎",
"email": "test@mail.com",
"password": "password"
}

送信ボタンを押すと、下の方に 200 OK でレスポンスが返ってくることが確認できます。 Laravel 側で mysql の中身をみて、ユーザーが登録されていることも確認してみてください。

ログイン処理

次に、ログイン処理を実装します。app/Http/Controllers/Auth/LoginController.phpに以下のコードを追加してください。

app/Http/Controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class LoginController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string',
]);

if (!auth()->attempt($request->only('email', 'password'))) {
return response()->json(['message' => 'Unauthorized'], 401);
}

return response()->json(['token' => $request->user()->createToken('token')->plainTextToken]);
}
}

Userモデルにも修正が必要なので、ファイルを開いて以下のコードを追加してください。

app/Models/User.php
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens; // HasApiTokens を追加
...

postmanを使ってログイン処理を試してみましょう。http://localhost/api/loginにリクエストを送り、以下の JSON を入力してください。

{
"email": "test@mail.com",
"password": "password"
}

正しく実行できると以下のように token のレスポンスが返ってきます。

alt text

認証保護とトークンの利用

取得したトークンを使って、認証が必要なエンドポイントにアクセスすることができます。 最初に作ったsampleエンドポイントに認証をかけてみましょう。

routes/api.phpを開いて、以下のように修正してください。

routes/api.php

// 省略

Route::get('/sample', function () {
return response()->json(['message' => 'Hello World!']);
})->middleware('auth:sanctum');

middleware auth:sanctumによって、未認証の場合のアクセスを制限することができます。 postman から試してみましょう。 header に Accept:application/jsonを設定するのを忘れないようにしてください。

alt text

レスポンスとして、{"message": "Unauthenticated."}が返ってくることが確認できます。

ヒント

ブラウザから認証保護されているルートにアクセスすると、login ページにリダイレクトされてしまいます。(login ページを実装していないので下記のようなエラー画面が出ます。)

ブラウザからのアクセスには、Accept:application/json がヘッダーに設定されないからです。

alt text

ログイン処理で取得したトークンを使って、認証を通過させることができます。

postman のヘッダーに、Authorization: Bearer {取得したトークン}を追加してリクエストを送信してみてください。

alt text

正しく実行できると、{"message":"Hello World!"}が返ってくることが確認できます。

トークンの扱い

フロントエンドでトークンを扱う場合、localStoragecookieに保存しておくことが一般的です。

ログイン画面でログインエンドポイントにリクエストを送り、トークンを取得したら、localStorageに保存しておきます。

localStorage.setItem("token", "取得したトークン");

そして、認証が必要なリクエストを送る際に、localStorageからトークンを取得して、Authorizationヘッダーに設定してリクエストを送ります。

const token = localStorage.getItem("token");

fetch("http://localhost/api/sample", {
method: "GET",
headers: {
Accept: "application/json",
Authorization: `Bearer ${token}`,
},
});

ログアウトする際は、localStorageからトークンを削除します。

localStorage.removeItem("token");

CORS の設定

API サーバーを別のドメインからアクセスする場合、CORS の設定が必要になります。フロントエンドとバックエンドを分けて実装する場合は、基本的に別ドメインになるため、CORS の設定が必要です。

以下のコマンドを実行して、CORS の設定ファイルを生成します。

sail artisan config:publish cors

config/cors.phpが生成されるので、以下のように設定してください。

config/cors.php
...
'allowed_origins' => ['http://localhost:3000'],
...

3000 は Next.js のデフォルトのポート番号です。フロントエンドのポート番号に合わせて設定してください。 また本番環境では、本番のドメインを設定してください。

以上で Laravel API サーバーの構築準備は完了です。