Laravel 12 实现 API 登录令牌认证
在 Laravel 12 中实现基于令牌(Token)的 API 认证,可以使用 Laravel Sanctum 或 Laravel Passport。以下是两种方式的实现方法:
方法一:使用 Laravel Sanctum (轻量级 API 认证)
1. 安装 Sanctum
composer require laravel/sanctum
2. 发布 Sanctum 迁移和配置文件
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
3. 运行数据库迁移
php artisan migrate
4. 配置 Sanctum
在 config/sanctum.php 中配置(通常保持默认即可)
5. 修改用户模型
在 app/Models/User.php 中添加 HasApiTokens trait:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
// ...
}
6. 创建认证路由
在 routes/api.php 中添加:
use App\Http\Controllers\AuthController;
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->post('/logout', [AuthController::class, 'logout']);
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
7. 创建认证控制器
php artisan make:controller AuthController
在 app/Http/Controllers/AuthController.php 中:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
public function login(Request $request)
{
if (!Auth::attempt($request->only('email', 'password'))) {
return response()->json([
'message' => 'Invalid login details'
], 401);
}
$user = User::where('email', $request['email'])->firstOrFail();
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'access_token' => $token,
'token_type' => 'Bearer',
]);
}
public function logout(Request $request)
{
$request->user()->currentAccessToken()->delete();
return response()->json([
'message' => 'Successfully logged out'
]);
}
}
8. 测试 API
使用 Postman 或 cURL 测试:
登录请求:
curl --location --request POST 'http://your-app.test/api/login' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "user@example.com",
"password": "password"
}'
获取用户信息:
curl --location --request GET 'http://your-app.test/api/user' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_TOKEN_HERE'
方法二:使用 Laravel Passport (OAuth2 全功能实现)
1. 安装 Passport
composer require laravel/passport
2. 运行数据库迁移
php artisan migrate
3. 安装 Passport
php artisan passport:install
4. 配置 Passport
在 app/Models/User.php 中添加:
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
// ...
}
在 config/auth.php 中设置 API 驱动:
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
5. 创建认证路由
在 routes/api.php 中添加:
use App\Http\Controllers\AuthController;
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:api')->post('/logout', [AuthController::class, 'logout']);
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
6. 创建认证控制器
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (!Auth::attempt($credentials)) {
return response()->json([
'message' => 'Unauthorized'
], 401);
}
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->accessToken;
return response()->json([
'access_token' => $token,
'token_type' => 'Bearer',
'expires_at' => $tokenResult->token->expires_at->toDateTimeString()
]);
}
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out'
]);
}
}
令牌刷新机制(可选)
如果需要实现令牌刷新功能,可以添加以下路由和方法:
Route::post('/refresh', [AuthController::class, 'refresh']);
// 在 AuthController 中添加
public function refresh(Request $request)
{
$user = $request->user();
$user->token()->revoke();
$tokenResult = $user->createToken('Personal Access Token');
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => $tokenResult->token->expires_at->toDateTimeString()
]);
}