本文共 5801 字,大约阅读时间需要 19 分钟。
在开始之前,确保已完成以下步骤:
安装 Laravel 和相关依赖:
composer require laravel/laravelphp artisan migrate
生成密码授权客户端密钥:
php artisan passport:keys
配置根路径推送 MIDI:
php artisan vendor:publish --tag=passport
注册 route 和模型:
use App\Models\Passport\Token;use App\Models\Passport\Client;class AuthServiceProvider extends ServiceProvider{ protected function boot() { $this->registerPolicies(); Passport::routes(); Passport::useTokenModel(Token::class); Passport::useClientModel(Client::class); }}
设置 Token 过期时间:
Passport::tokensExpireIn(now()->addDays(15));Passport::refreshTokensExpireIn(now()->addDays(30));Passport::personalAccessTokensExpireIn(now()->addMonths(6));
namespace App\Models\Passport;use Laravel\Passport\HasApiTokens;class Token extends HasApiTokens{ public function scopeActivities() { return $this->scopes('activities:results'); }}
创建新客户端:
php artisan passport:client
API 管理客户端:
axios.get('/oauth/clients') .then(response => { console.log(response.data); });
更新客户端信息:
axios.put('/oauth/clients/' + clientId, data) .then(response => { console.log(response.data); }) .catch(response => { console.error(response.data); });
删除客户端:
axios.delete('/oauth/clients/' + clientId) .then(response => { console.log(response.data); });
获取授权码:
Route::get('/redirect', function (Request $request) { $state = $request->session()->put('state', Str::random(40)); $query = http_build_query([ 'client_id' => 'client-id', 'redirect_uri' => 'http://example.com/callback', 'response_type' => 'code', 'scope' => '', 'state' => $state, ]); return redirect('http://your-app.com/oauth/authorize?'.$query);});
验证授权码:
Route::get('/callback', function (Request $request) { $state = $request->session()->pull('state'); throw_unless(strlen($state) > 0 && $state === $request->state, InvalidArgumentException::class); $response = new GuzzleHttp\Client() ->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'authorization_code', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'redirect_uri' => 'http://example.com/callback', 'code' => $request->code, ], ]); return json_decode((string) $response->getBody(), true);});
$http = new GuzzleHttp\Client;$response = $http->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'password', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'username' => 'taylor@laravel.com', 'password' => 'my-password', 'scope' => '', // '*'仅限于密码模式和客户端模式 ],]);return json_decode((string) $response->getBody(), true);
Passport::enableImplicitGrant();Route::get('/redirect', function (Request $request) { $state = $request->session()->put('state', Str::random(40)); $query = http_build_query([ 'client_id' => 'client-id', 'redirect_uri' => 'http://example.com/callback', 'response_type' => 'token', 'scope' => '', // 可传递多个 scope 'state' => $state, ]); return redirect('http://your-app.com/oauth/authorize?'.$query);});
注册客户端路由:
use Laravel\Passport\Http\Middleware\CheckClientCredentials;protected $routeMiddleware = [ 'client' => CheckClientCredentials::class,];Route::get('/orders', function (Request $request) { // ...})->middleware('client');
自定义作用域权限:
Passport::tokensCan([ 'place-orders' => 'Place orders', 'check-status' => 'Check order status',]);Passport::setDefaultScope(['check-status', 'place-orders']);
$response = $client->request('/api/user', [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'Bearer ' . $accessToken, },]);
$routeMiddleware = [ 'scope' => CheckForAnyScope::class, 'scopers' => CheckScopes::class,];protected $routeMiddleware = array_merge( $this->routeMiddleware, [ 'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class, ]);
测试 API 成功响应:
$response = $this->get('/api/orders');$response->assertStatus(200);
测试 Token 验证失败:
$response = $this->post('/api/orders', [], ['unauth']);$response->assertStatus(403);
try { // 执行业务逻辑} catch (\Exception $e) { Log::error("系统错误: " . $e->getMessage()); throw $e;}
protected $listen = [ Event::class . ':AccessTokenCreated' => [ Listen::baef('App\Listeners\RevokeOldTokens') ], Event::class . ':RefreshTokenCreated' => [ Listen::baef('App\Listeners\PruneOldTokens') ],];
自定义授权页面:
php artisan vendor:publish --tag=passport-views
Cookie animation 自定义:
public function boot(){ $this->registerPolicies(); Passport::routes(); Passport::cookie('custom_name');}}class AuthServiceProvider extends ServiceProvider{ public function boot() { parent::boot(); $this->app->singleton(WebMiddleware::class, function () { return new WebMiddleware(); }); }}
使用TestThese Methods:
public function testServerCreation(){ Passport::actingAs( factory(User::class)->create(), ['create-servers'] ); $response = $this->post('/api/create-server'); $response->assertStatus(201);}
Client Mode 测试:
public function testGetOrders(){ Passport::actingAsClient( factory(Client::class)->create(), ['check-status'] ); $response = $this->get('/api/orders'); $response->assertStatus(200);}
文章参考的内容均基于最新版本的 Laravel Passport 文档,注重实用性和可读性,同时添加了一些高级功能的示例,旨在帮助开发者快速上手 Laravel Passport,灵活应对多种认证场景。
转载地址:http://ougyk.baihongyu.com/