本文目录导读:

- 项目准备
- 安装Laravel Passport
- 配置Passport
- 配置AuthServiceProvider
- 配置路由
- 创建认证控制器
- 配置中间件
- Passport前端组件 (可选)
- 测试API
- 密码授权方式
- 刷新令牌
- 安全建议
- 数据库优化
- 常用命令
- 完整目录结构
我来详细介绍如何搭建Laravel OAuth服务器,最常用的方案是使用Laravel Passport。
项目准备
创建Laravel项目
# 创建新项目 composer create-project laravel/laravel oauth-server cd oauth-server # 配置数据库 (.env文件) DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=oauth_server DB_USERNAME=root DB_PASSWORD=
安装Laravel Passport
# 安装Passport包 composer require laravel/passport # 创建数据库迁移 php artisan migrate # 安装Passport相关组件 php artisan passport:install
配置Passport
修改User模型
// app/Models/User.php
<?php
namespace App\Models;
use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
配置Auth认证服务
// config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
配置AuthServiceProvider
// app/Providers/AuthServiceProvider.php
<?php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\Models\Model' => 'App\Policies\ModelPolicy',
];
public function boot()
{
$this->registerPolicies();
// 配置令牌过期时间
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
Passport::personalAccessTokensExpireIn(now()->addMonths(6));
}
}
配置路由
// routes/api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\AuthController;
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
Route::middleware('auth:api')->group(function () {
Route::get('user', [AuthController::class, 'user']);
Route::post('logout', [AuthController::class, 'logout']);
});
// 客户端管理路由
Route::middleware('auth:api')->group(function () {
Route::get('clients', [AuthController::class, 'clients']);
Route::post('clients', [AuthController::class, 'storeClient']);
Route::get('personal-access-tokens', [AuthController::class, 'tokens']);
});
创建认证控制器
// app/Http/Controllers/Api/AuthController.php
<?php
namespace App\Http\Controllers\Api;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\ClientRepository;
class AuthController extends Controller
{
public function register(Request $request)
{
$this->validate($request, [
'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),
]);
$token = $user->createToken('Personal Access Token');
return response()->json([
'success' => true,
'message' => 'User registered successfully',
'user' => $user,
'access_token' => $token->accessToken
], 201);
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
$credentials = [
'email' => $request->email,
'password' => $request->password
];
if (Auth::attempt($credentials)) {
$user = Auth::user();
$token = $user->createToken('Personal Access Token');
return response()->json([
'success' => true,
'message' => 'Login successful',
'user' => $user,
'access_token' => $token->accessToken
]);
}
return response()->json([
'success' => false,
'message' => 'Invalid credentials'
], 401);
}
public function user(Request $request)
{
return response()->json([
'success' => true,
'user' => $request->user()
]);
}
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([
'success' => true,
'message' => 'Successfully logged out'
]);
}
// 客户端管理功能
public function clients(Request $request)
{
$clients = $request->user()->clients;
return response()->json([
'success' => true,
'clients' => $clients
]);
}
public function storeClient(Request $request)
{
$this->validate($request, [
'name' => 'required|string',
'redirect' => 'required|string|url'
]);
$clientRepository = app(ClientRepository::class);
$client = $clientRepository->create(
$request->user()->id,
$request->name,
$request->redirect
);
return response()->json([
'success' => true,
'client' => $client
], 201);
}
}
配置中间件
// app/Http/Kernel.php
protected $routeMiddleware = [
// ... 其他中间件
'auth:api' => \Laravel\Passport\Http\Middleware\CheckCredentials::class,
];
Passport前端组件 (可选)
# 生成API管理界面
php artisan vendor:publish --tag=passport-components
# 将Vue组件编译到你的应用
# 在resources/js/app.js中添加:
require('./components/passport/Clients.vue');
测试API
注册用户
curl -X POST http://localhost:8000/api/register \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@example.com",
"password": "password123"
}'
登录获取令牌
curl -X POST http://localhost:8000/api/login \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "password123"
}'
使用令牌访问受保护接口
curl -X GET http://localhost:8000/api/user \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
密码授权方式
# 使用密码授权获取令牌
curl -X POST http://localhost:8000/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "password",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"username": "user@example.com",
"password": "password",
"scope": ""
}'
刷新令牌
// 在后端添加刷新令牌路由
Route::post('refresh-token', function (Request $request) {
$http = new \GuzzleHttp\Client;
$response = $http->post(config('app.url') . '/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => $request->refresh_token,
'client_id' => config('passport.client_id'),
'client_secret' => config('passport.client_secret'),
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
});
安全建议
// 在config/passport.php中配置更强安全性
'password_grant' => [
'encryption_key' => env('PASSPORT_ENCRYPTION_KEY'),
],
// 限制请求频率(app/Http/Kernel.php)
'throttle:60,1'
数据库优化
-- 添加索引优化查询 CREATE INDEX idx_oauth_access_tokens_user_id ON oauth_access_tokens(user_id); CREATE INDEX idx_oauth_refresh_tokens_access_token_id ON oauth_refresh_tokens(access_token_id);
常用命令
# 查看客户端列表 php artisan passport:client --password # 创建个人访问令牌 php artisan passport:client --personal # 导出加密密钥 php artisan passport:keys # 清理过期令牌 php artisan passport:purge --revoked --expired
完整目录结构
├── app/
│ ├── Http/
│ │ └── Controllers/
│ │ └── Api/
│ │ └── AuthController.php
│ └── Models/
│ └── User.php
├── config/
│ └── auth.php
├── routes/
│ └── api.php
└── database/
└── migrations/
└── xxx_create_oauth_tables.php
这样就完成了基本的OAuth服务器搭建,你可以根据需要调整令牌格式、过期时间、权限范围等配置。