技術 7 分鐘閱讀
Laravel 認證系統實作:從基礎到進階
前言
認證系統是幾乎每個專案都需要的功能。Laravel 提供了非常完善的認證機制,這篇文章帶你從基礎的登入註冊到進階的 API Token 認證和權限管理。
Laravel Breeze:快速開始
如果是全新專案,用 Breeze 最快:
composer require laravel/breeze --dev
php artisan breeze:install react
npm install && npm run build
php artisan migrate
Breeze 會自動建立完整的認證頁面:註冊、登入、忘記密碼、Email 驗證。搭配 Inertia.js 和 React,前後端一次搞定。
Sanctum API 認證
如果你的前端是 SPA 或需要提供 API 給行動裝置使用,Sanctum 是最佳選擇。
安裝與設定
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
在 User Model 加入 Trait:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
Token 認證
// 登入並發放 Token
class AuthController extends Controller
{
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
return response()->json([
'message' => '帳號或密碼錯誤',
], 401);
}
// 建立 Token,可設定權限
$token = $user->createToken('api-token', ['read', 'write'])->plainTextToken;
return response()->json([
'user' => $user,
'token' => $token,
]);
}
public function logout(Request $request)
{
// 撤銷當前 Token
$request->user()->currentAccessToken()->delete();
return response()->json([
'message' => '已登出',
]);
}
}
保護路由
// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::apiResource('products', ProductController::class);
});
SPA 認證(Cookie-based)
對於同網域的 SPA,可以使用 Cookie 認證,不需要管理 Token:
// config/sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS',
'localhost,localhost:3000,localhost:5173'
)),
前端在呼叫 API 前先取得 CSRF Cookie:
// 初始化 CSRF
await fetch('/sanctum/csrf-cookie', {
credentials: 'include',
});
// 之後的 API 呼叫都會自動帶上 Cookie
const response = await fetch('/api/user', {
credentials: 'include',
});
社群登入:Socialite
安裝
composer require laravel/socialite
Google 登入實作
// config/services.php
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT_URL'),
],
// routes/web.php
Route::get('/auth/google', [SocialiteController::class, 'redirect']);
Route::get('/auth/google/callback', [SocialiteController::class, 'callback']);
class SocialiteController extends Controller
{
public function redirect()
{
return Socialite::driver('google')->redirect();
}
public function callback()
{
$googleUser = Socialite::driver('google')->user();
$user = User::updateOrCreate(
['email' => $googleUser->getEmail()],
[
'name' => $googleUser->getName(),
'google_id' => $googleUser->getId(),
'avatar' => $googleUser->getAvatar(),
'password' => Hash::make(Str::random(24)),
]
);
Auth::login($user);
return redirect('/dashboard');
}
}
權限管理:Policy 與 Gate
定義 Policy
php artisan make:policy ProductPolicy --model=Product
class ProductPolicy
{
public function update(User $user, Product $product): bool
{
return $user->id === $product->user_id;
}
public function delete(User $user, Product $product): bool
{
return $user->id === $product->user_id
|| $user->role === 'admin';
}
}
在 Controller 中使用
public function update(Request $request, Product $product)
{
$this->authorize('update', $product);
$product->update($request->validated());
return response()->json($product);
}
Gate 定義
適合不需要 Model 的權限判斷:
// app/Providers/AuthServiceProvider.php
Gate::define('manage-users', function (User $user) {
return $user->role === 'admin';
});
if (Gate::allows('manage-users')) {
// 管理者才能執行
}
密碼重設流程
Laravel 內建的密碼重設流程已經很完整。如果需要自訂:
// 自訂重設密碼的 Email 內容
class User extends Authenticatable
{
public function sendPasswordResetNotification($token)
{
$url = config('app.frontend_url') . '/reset-password?token=' . $token;
$this->notify(new ResetPasswordNotification($url));
}
}
Email 驗證
class User extends Authenticatable implements MustVerifyEmail
{
// 加上 MustVerifyEmail 介面
}
// 路由加上 verified middleware
Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
安全性注意事項
Rate Limiting
防止暴力破解登入:
// routes/api.php
Route::post('/login', [AuthController::class, 'login'])
->middleware('throttle:5,1'); // 每分鐘最多 5 次
Token 有效期
// config/sanctum.php
'expiration' => 60 * 24, // Token 24 小時後過期
敏感操作需要重新驗證
Route::middleware(['auth', 'password.confirm'])->group(function () {
Route::delete('/account', [AccountController::class, 'destroy']);
});
結語
Laravel 的認證系統已經幫你處理了大部分的工作,從簡單的登入註冊到複雜的 API 認證和權限管理都有對應的解決方案。在接案專案中,善用這些內建功能可以省下大量開發時間,也能確保安全性。重要的是理解每個方案的適用場景,選擇最適合你專案的做法。
#Laravel #認證 #Sanctum #PHP