Laravel 11 Sanctum JWT API 認證建置教學

Laravel

在 Laravel 11 使用內建的 Sanctum 建置 JWT API 認證,包含使用者註冊、登入、登出及使用者資訊。

Laravel 11 JWT API 建置設定

建立 controller API → /app/Http/Controllers/Api/ApiController.php

php artisan make:controller Api/ApiController

產生 routes API 檔案。

php artisan install:api

產生 JWT API 資料庫資料表。

php artisan migrate

設定 Models API Token → /app/Models/User.php

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

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

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

/**
 * 以下省略
 */

設定註冊、登入、登出及使用者資訊 API → /app/Http/Controllers/Api/ApiController.php

<?php

namespace App\Http\Controllers\Api;

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

use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;

class ApiController extends Controller
{
    // Register API, Login API, Profile API, Logout API

    // POST [name, email, password]
    public function register (Request $request) {
        // Validation
        $request->validate([
            'name' => 'required|string',
            'email' => 'required|string|email|unique:users',
            'password' => 'required|confirmed',
        ]);

        // User
        User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => bcrypt($request->password)
        ]);

        return [
            'status' => true,
            'message' => 'User registered successfully',
            'data' => []
        ];
    }

    // POST [email, password]
    public function login (Request $request) {
        // Validation
        $request->validate([
            'email' => 'required|email|string',
            'password' => 'required',
        ]);

        // Email check
        $user = User::where('email', $request->email)->first();

        if (!empty($user)) {
            // User exists
            if (Hash::check($request->password, $user->password)) {
                // Password matched
                $token = $user->createToken('mytoken')->plainTextToken;

                return [
                    'status' => true,
                    'message' => 'User loggen in',
                    'token' => $token,
                    'data' => []
                ];
            } else {
                return [
                    'status' => false,
                    'message' => 'Invalid password',
                    'data' => [],
                ];
            }
        } else {
            return [
                'status' => false,
                'message' => "Email doesn't match with records",
                'data' => []
            ];
        }
    }

    // GET [Auth: Token]
    public function profile () {
        $query = auth()->user();

        $queryCompany = DB::table('company')
            ->select(
                'name',
            )
            ->where('id', $query->company_id)
            ->get();

        $query['company_name'] = $queryCompany[0]->name;
        
        return [
            'status' => true,
            'message' => 'Profile Information',
            'data' => $query,
            'id' => auth()->user()->id
        ];
    }

    // GET [Auth: Token]
    public function logout () {
        auth()->user()->tokens()->delete();

        return [
            'status' => true,
            'message' => 'User logged out',
            'data' => []
        ];
    }
}

設定 routers → /routes/api.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

use App\Http\Controllers\Api\ApiController;

Route::post('login', [ApiController::class, 'login']);
Route::post('register', [ApiController::class, 'register']);    // https://app-api.dancelight.com.tw/api/register

// Protected Routes
Route::group([
    'middleware' => ['auth:sanctum']
], function () {
    Route::get('profile', [ApiController::class, 'profile']);
    Route::get('logout', [ApiController::class, 'logout']);
});

參考

發表留言