13
5

Laravel(API)で認証機能を作成してみた。

Last updated at Posted at 2024-04-04

はじめに

普段はRailsで実装をしている私が、Laravelで認証機能を作成しました。
「LaravelでAPIモードの実装ってどうやるんだ??」と気になったこともあり、こちらの記事を作成しました。
(ログインのみの実装です)

Laravel初学者の方々への一助になれば幸いです。

開発環境
PHP 8.1.27
Laravel 10.46.0

実装

マイグレーション

説明の関係上、ログインに必要なカラムのみ以下に記載しています。

database/migrations/2014_10_12_000000_create_users_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('email')->unique();
            $table->string('password');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};

モデル

$fillableプロパティは、Eloquentモデルでマスアサインメントを行う際に許可される属性(カラム)を指定するためのプロパティです。
マスアサインメントとは、一度に複数の属性をまとめてモデルに設定することです。

app/Models/User.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
    ];

    protected $casts = [
        'password' => 'hashed',
    ];
}

コントローラー

response()->jsonメソッドでJSONを返します。
Attemptは基本的に、ユーザーが提供した資格情報を使用してユーザーのログインを試行します。
資格情報は、下記のコードの$credentialsにあたリます。
認証が成功した場合、attemptメソッドはtrueを返します。それ以外の場合は、falseを返します。

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

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;

class AuthenticatedSessionController extends Controller
{

    public function store(LoginRequest $request): \Illuminate\Http\JsonResponse
    {
        try {
            # emailとpasswordのキーを持つ連想配列から値を取り出して、credentials変数に代入する
            $credentials = $request->only('email', 'password');
    
            # credentials変数の情報を渡し、Authファサードを介してログイン処理を行う。DB内のユーザーと一致したらattemptでtrue、存在しなかったらfalseを返す。
            if(Auth::attempt($credentials)) {
                # ユーザーを認証する
                $request->authenticate();
    
                # セッションIDの発行
                $request->session()->regenerate();
    
                return response()->json([
                    'status' => 'success',
                    'message' => 'ログインが成功しました'
                ], 200);
            } else {
                return response()->json([
                    'status' => 'error',
                    'message' => 'ログインに失敗しました'
                ], 401);
           }
        } catch (\Illuminate\Auth\AuthenticationException $e) {
            return response()->json([
                'status' => 'error',
                'message' => '予期せぬエラーが発生しました'
            ], 500);
        }
    }

}

ルーティング

storeメソッドを呼び出して、認証を行います。
authミドルウェアを使用することでセッションの有効性を確認し、新しいセッションを作成・更新します。
(Railsにもミドルウェアの概念があるが、Rackミドルウェアのスタック内で実行されているようです)

routes/auth.php
<?php

use App\Http\Controllers\Auth\AuthenticatedSessionController;
use Illuminate\Support\Facades\Route;


Route::post('/api/login', [AuthenticatedSessionController::class, 'store'])
                ->middleware('auth');

Seedデータ

ログインするためのユーザーの初期データです。
Hash::make~のパスワードハッシュ化の処理は手動で実装しています。

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use DateTime;

class UsersTableSeeder extends Seeder
{
    public function run()
    {
        DB::table('users')->insert([
            'name' => 'sample1',
            'email' => 'sample1@example.com',
            'password' => Hash::make('password'),
            'created_at' => new DateTime(),
            'updated_at' => new DateTime()
        ]);
    }
}

結果

Postmanで動作確認を行いました。
手順

  1. Bodyタグのform-dataでemailとpasswordを入力する
  2. http://localhost/api/login でPOSTリクエストを送信する
  3. 「ログインに成功しました」といったメッセージがJSONで表示されれば成功です
  4. 違うメールアドレスかパスワードを入力してログインに失敗すればOKです

ログイン成功
316219488-3a63b8ab-7898-485d-bffd-8bf86aad98f3.png

ログイン失敗
スクリーンショット 2024-04-05 6.42.54.png

終わりに

今回は公式ドキュメントなどを見ながら、標準の認証機能を作成しました。
Laravel初学者なのでまだまだ理解が浅いですが、時間がある時にその他の実装方法も勉強していければと思います。

参考記事

Laravel 10.x 認証
Laravel 10.x ハッシュ(https://readouble.com/laravel/10.x/ja/authentication.html)
Laravel 10.x HTTPレスポンス
Laravel で認証パラメータを追加する
Auth::login() vs Auth::attempt()

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5