隨著API的使用逐漸普及,保護(hù)API的安全性和可擴(kuò)展性變得越來越關(guān)鍵。而OAuth2已經(jīng)成為了一種廣泛采用的API安全協(xié)議,它允許應(yīng)用程序通過授權(quán)來訪問受保護(hù)的資源。為了實(shí)現(xiàn)OAuth2身份驗(yàn)證,Laravel Passport提供了一種簡單、靈活的方式。在本篇文章中,我們將學(xué)習(xí)如何使用Laravel Passport實(shí)現(xiàn)API OAuth2身份驗(yàn)證。
Laravel Passport是官方提供的一個(gè)OAuth2服務(wù)器庫,可以輕松地添加OAuth2身份驗(yàn)證到您的Laravel應(yīng)用程序中。它針對(duì)Laravel框架的客戶端提供了API身份驗(yàn)證,通過token來保護(hù)API并限制資源的訪問。通過很少的配置步驟,你可以創(chuàng)建一個(gè)安全的OAuth2服務(wù)器并為你的API提供身份驗(yàn)證和授權(quán)。
為了開始使用Laravel Passport,你需要安裝它。你可以通過Composer包管理器安裝它:
composer require laravel/passport
一旦你安裝了Laravel Passport,你需要運(yùn)行migrations來創(chuàng)建必要的數(shù)據(jù)庫表:
php artisan migrate
為了啟用Laravel Passport,你需要注冊(cè)ServiceProvider和中間件。在config/app.php文件中添加以下ServiceProvider和中間件:
'providers' => [ // ... LaravelPassportPassportServiceProvider::class, ], 'middleware' => [ // ... LaravelPassportHttpMiddlewareCreateFreshApiToken::class, ],
Laravel Passport需要一個(gè)用于發(fā)行access token和refresh token的“keys”表。運(yùn)行以下命令將生成此表:
php artisan passport:install
這會(huì)創(chuàng)建一個(gè)加密的RSA秘鑰對(duì)用于簽署和驗(yàn)證tokens,以及一個(gè)名為“personal_access_client”的客戶端和一個(gè)名為“password_client”的客戶端。這兩個(gè)客戶端用于創(chuàng)建不同類型的tokens。第一個(gè)客戶端用于生成個(gè)人訪問tokens,這些tokens允許客戶端訪問任何以O(shè)Auth2身份驗(yàn)證方式保護(hù)的API端點(diǎn)。第二個(gè)客戶端用于創(chuàng)建密碼授權(quán)tokens,這些tokens允許客戶端通過用戶名和密碼獲取access token。
在這個(gè)過程中,你還需要在你的config/auth.php文件中配置Laravel Passport。你需要將passport驅(qū)動(dòng)器添加到API守衛(wèi),以便Laravel Passport來處理一切與OAuth2相關(guān)的東西。示例如下:
'guards' => [ // ... 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
現(xiàn)在我們已經(jīng)完成了設(shè)置,我們可以開始創(chuàng)建API路由和控制器了。
首先,你需要定義API路由。例如,假設(shè)你有一個(gè)API端點(diǎn)來獲取一個(gè)任務(wù)列表:
Route::get('/tasks', 'TaskController@index')->middleware('auth:api');接下來,你需要?jiǎng)?chuàng)建一個(gè)控制器來處理請(qǐng)求并響應(yīng)任務(wù):
class TaskController extends Controller
{
public function index()
{
$tasks = Task::all();
return response()->json([
'tasks' => $tasks,
]);
}
}在middleware方法中加入“auth:api”參數(shù)以指示我們使用API守衛(wèi)來保護(hù)路由。
現(xiàn)在讓我們看看如何執(zhí)行OAuth2身份驗(yàn)證并獲得access token。你需要?jiǎng)?chuàng)建一個(gè)客戶端,該客戶端將使用密碼授權(quán)OAuth2 flow來獲得access token。這樣你就可以通過API請(qǐng)求在API端點(diǎn)上進(jìn)行身份驗(yàn)證了。
你可以在Laravel Passport的客戶端列表中創(chuàng)建一個(gè)新客戶端,或者在你的代碼中使用Passport::client()方法為客戶端生成一個(gè)隨機(jī)的client id和client secret。你可以將client id和client secret保存在你的.env文件或你可以在你的Passport::client()方法中直接提供它們。此方法將創(chuàng)建一個(gè)新的客戶端,并返回client id和client secret:
use LaravelPassportClient;
use IlluminateSupportFacadesDB;
$client = $this->createClient();
public function createClient()
{
$client = Client::forceCreate([
'user_id' => null,
'name' => 'Test Client',
'secret' => str_random(40),
'redirect' => '',
'personal_access_client' => false,
'password_client' => true,
'revoked' => false,
]);
DB::table('oauth_client_grants')->insert([
'client_id' => $client->id,
'grant_id' => 1,
]);
return $client;
}現(xiàn)在我們已經(jīng)有了一個(gè)客戶端,我們需要在控制器中使用Laravel Passport來獲取access token并使用它來訪問受保護(hù)的API端點(diǎn)。我們需要使用以下代碼在控制器中實(shí)現(xiàn)OAuth2身份驗(yàn)證:
use IlluminateSupportFacadesAuth;
use LaravelPassportClientRepository;
class TaskController extends Controller
{
protected $clients;
public function __construct(ClientRepository $clients)
{
$this->clients = $clients;
}
public function index()
{
$client = $this->clients->find(2);
$response = $this->actingAsClient($client, function () {
return $this->get('/api/tasks');
});
return $response->getContent();
}
protected function actingAsClient($client, $callback, $scopes = [])
{
$proxy = new LaravelPassportHttpControllersAccessTokenController();
$token = $proxy->issueToken(
$this->getPersonalAccessTokenRequest($client, $scopes)
);
Auth::guard('web')->loginUsingId($client->user_id);
$callback($token);
return $this->app->make(IlluminateHttpRequest::class);
}
protected function getPersonalAccessTokenRequest($client, $scopes = [])
{
$data = [
'grant_type' => 'client_credentials',
'client_id' => $client->id,
'client_secret' => $client->secret,
'scope' => implode(' ', $scopes),
];
return IlluminateHttpRequest::create('/oauth/token', 'POST', $data);
}
}使用actingAsClient()方法,我們可以模擬以客戶端身份運(yùn)行請(qǐng)求,控制器中的任何方法都可以使用該方法進(jìn)行OAuth2身份驗(yàn)證。我們需要傳遞一個(gè)客戶端對(duì)象,一個(gè)回調(diào)函數(shù)以執(zhí)行API請(qǐng)求,并可選地傳遞添加到請(qǐng)求中的權(quán)限。
現(xiàn)在我們已經(jīng)完成了Laravel Passport的OAuth2身份驗(yàn)證配置,通過使用上述代碼模式,我們可以輕松地在我們的API端點(diǎn)上實(shí)現(xiàn)安全的OAuth2身份驗(yàn)證。 Passport是一個(gè)相對(duì)較新的項(xiàng)目。但是,它是與Laravel完美集成的,并且提供了多種OAuth2身份驗(yàn)證服務(wù),使您能夠輕松地向您的API添加身份驗(yàn)證和授權(quán)。如果你在運(yùn)行一個(gè)Laravel應(yīng)用程序并需要添加OAuth2身份驗(yàn)證,Laravel Passport是實(shí)現(xiàn)此目的的理想選擇。






