前言
也可以關(guān)注我的個(gè)人博客
?這里摘錄下laravel5.5教程的認(rèn)證文檔,做個(gè)總結(jié),方便今后查閱。
安裝passport
使用 Composer 依賴包管理器安裝 Passport :
composer require laravel/passport
接下來(lái),將 Passport 的服務(wù)提供者注冊(cè)到配置文件 config/app.php 的 providers 數(shù)組中:
Laravel\Passport\PassportServiceProvider::class,
Passport 使用服務(wù)提供者注冊(cè)內(nèi)部的數(shù)據(jù)庫(kù)遷移腳本目錄既荚,所以上一步完成后,你需要更新你的數(shù)據(jù)庫(kù)結(jié)構(gòu)栋艳。Passport 的遷移腳本會(huì)自動(dòng)創(chuàng)建應(yīng)用程序需要的客戶端數(shù)據(jù)表和令牌數(shù)據(jù)表:
php artisan migrate
如果你不打算使用 Passport 的默認(rèn)遷移恰聘,你應(yīng)該在 AppServiceProvider 的 register 方法中調(diào)用
Passport :: ignoreMigrations
方法。 你可以導(dǎo)出這個(gè)默認(rèn)遷移用php artisan vendor:publish --tag=passport-migrations
命令吸占。
接下來(lái)晴叨,你需要運(yùn)行 passport:install
命令來(lái)創(chuàng)建生成安全訪問(wèn)令牌時(shí)用到的加密密鑰,同時(shí)矾屯,這條命令也會(huì)創(chuàng)建「私人訪問(wèn)」客戶端和「密碼授權(quán)」客戶端:
php artisan passport:install
上面命令執(zhí)行后兼蕊,請(qǐng)將 Laravel\Passport\HasApiTokens Trait 添加到 App\User 模型中,這個(gè) Trait 會(huì)給你的模型提供一些輔助函數(shù)件蚕,用于檢查已認(rèn)證用戶的令牌和使用作用域:
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
接下來(lái)孙技,需要在 AuthServiceProvider 的 boot 方法中調(diào)用 Passport::routes
函數(shù)。這個(gè)函數(shù)會(huì)注冊(cè)一些在訪問(wèn)令牌排作、客戶端牵啦、私人訪問(wèn)令牌的發(fā)放和吊銷過(guò)程中會(huì)用到的必要路由:
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
最后,需要將配置文件 config/auth.php 中 api 部分的授權(quán)保護(hù)項(xiàng)( driver )改為 passport 纽绍。此調(diào)整會(huì)讓你的應(yīng)用程序在接收到 API 的授權(quán)請(qǐng)求時(shí)使用 Passport 的 TokenGuard 來(lái)處理:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
到此為止蕾久,基本的設(shè)置已經(jīng)完成,接下來(lái)救來(lái)用passport開(kāi)始認(rèn)證吧拌夏。
使用passport
發(fā)放訪問(wèn)令牌
管理客戶端
首先僧著,接入應(yīng)用如果想要與你應(yīng)用的 API 進(jìn)行交互,必須先在你的應(yīng)用程序中注冊(cè)一個(gè)「客戶端」障簿。一般來(lái)說(shuō)盹愚,這個(gè)注冊(cè)過(guò)程需要開(kāi)發(fā)者提供兩部分信息:接入應(yīng)用名稱和用戶授權(quán)后的跳轉(zhuǎn)鏈接。
命令 passport:client#
創(chuàng)建客戶端最簡(jiǎn)單的方式是使用 Artisan 命令 passport:client 站故,你可以使用此命令創(chuàng)建自己的客戶端皆怕,用于測(cè)試 OAuth2 的功能。在你執(zhí)行 client 命令時(shí)西篓,Passport 會(huì)提示輸入更多關(guān)于你的客戶端的信息愈腾,最終會(huì)提供給你生成的客戶端的 ID 和 密鑰:
php artisan passport:client
執(zhí)行完成之后會(huì)生成 client ID 和client secret;
這些都是你的本地環(huán)境生成的,別人如果想使用的話還需要接下來(lái)的步驟岂津;
JSON API
考慮到你的用戶們并沒(méi)有辦法使用 client 命令虱黄,Passport 同時(shí)提供了用戶創(chuàng)建客戶端的 JSON API 。這樣你就不用再花時(shí)間編碼來(lái)實(shí)現(xiàn)客戶端創(chuàng)建吮成、更新和刪除的相關(guān)控制器邏輯了橱乱。
然而,你仍舊需要基于 Passport 的 JSON API 開(kāi)發(fā)一套前端界面粱甫,方便你的用戶管理他們授權(quán)的客戶端泳叠。下面我們會(huì)列出所有用于管理客戶端的 API,方便起見(jiàn)茶宵,我們使用 Axios 展示對(duì) API 的 HTTP 請(qǐng)求危纫。
GET /oauth/clients#
此接口會(huì)返回當(dāng)前認(rèn)證用戶的所有客戶端。主要用途是列出當(dāng)前用戶所有客戶端乌庶,方便用戶修改或刪除:
axios.get('/oauth/clients')
.then(response => {
console.log(response.data);
});
POST /oauth/clients#
此接口用于用戶創(chuàng)建新的客戶端叶摄。它需要兩部分?jǐn)?shù)據(jù):客戶端的名稱、客戶端的 redirect 鏈接安拟。當(dāng)用戶允許或拒絕授權(quán)請(qǐng)求后蛤吓,用戶都會(huì)被重定向到這個(gè) redirect 鏈接。
當(dāng)客戶端創(chuàng)建完成后糠赦,會(huì)生成此客戶端的 ID 和密鑰会傲,客戶端可以使用這兩個(gè)值從你的應(yīng)用程序請(qǐng)求訪問(wèn)令牌。此接口會(huì)返回新建客戶端實(shí)例的信息:
const data = {
name: 'Client Name',
redirect: 'http://example.com/callback'
};
axios.post('/oauth/clients', data)
.then(response => {
console.log(response.data);
})
.catch (response => {
// List errors on response...
});
PUT /oauth/clients/{client-id}#
此接口用于更新客戶端信息拙泽。它需要兩部分?jǐn)?shù)據(jù):客戶端的 name 和 redirect 鏈接淌山。當(dāng)用戶允許或拒絕授權(quán)請(qǐng)求后,用戶都會(huì)被重定向到這個(gè) redirect 鏈接顾瞻。此接口會(huì)返回被更新客戶端實(shí)例的信息:
const data = {
name: 'New Client Name',
redirect: 'http://example.com/callback'
};
axios.put('/oauth/clients/' + clientId, data)
.then(response => {
console.log(response.data);
})
.catch (response => {
// List errors on response...
});
DELETE /oauth/clients/{client-id}#
此接口用于刪除客戶端:
axios.delete('/oauth/clients/' + clientId)
.then(response => {
//
});
1.授權(quán)碼方式獲取token
添加一個(gè)路由到你的項(xiàng)目中:
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
});
這里的路由可以隨便定義泼疑,不一定非要是redirect
。
接下來(lái)定義callback的路由:
Route::get('/callback', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->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);
});
這里的redirect_uri
必須和上訴的保持一致荷荤。
2.密碼方式獲取token
創(chuàng)建密碼授權(quán)客戶端
如果想要通過(guò)密碼授權(quán)機(jī)制來(lái)發(fā)布令牌退渗,首先你需要?jiǎng)?chuàng)建一個(gè)密碼授權(quán)客戶端移稳。你可以使用帶有 --password 參數(shù)的 passport:client 命令。如果你已經(jīng)運(yùn)行了 passport:install 命令会油,那無(wú)需再單獨(dú)運(yùn)行此命令:
php artisan passport:client --password
當(dāng)你創(chuàng)建密碼授權(quán)客戶端后个粱,你可以向 /oauth/token 接口發(fā)起 POST 請(qǐng)求來(lái)獲取訪問(wèn)令牌,請(qǐng)求時(shí)需要帶有用戶的郵箱地址和密碼信息翻翩。注意都许,該接口已經(jīng)在 Passport::routes 方法中定義,所以無(wú)需再次手動(dòng)定義嫂冻。請(qǐng)求成功后胶征,服務(wù)端返回的 JSON 響應(yīng)數(shù)據(jù)中會(huì)帶有 access_token 和 refresh_token 屬性:
$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);
3.簡(jiǎn)化授權(quán)令牌
簡(jiǎn)化授權(quán)和通過(guò)授權(quán)碼授權(quán)相似; 區(qū)別是, 不需要通過(guò)授權(quán)碼去獲取令牌而是把令牌直接返回客戶端. 主要用在無(wú)法安全存儲(chǔ)證書(shū)場(chǎng)景中,這種授權(quán)在 JavaScript 和 移動(dòng)應(yīng)用 是最常用的. 開(kāi)啟授權(quán), 在 AuthServiceProvider 中調(diào)用 enableImplicitGrant 方法:
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::enableImplicitGrant();
}
調(diào)用上面方法開(kāi)啟授權(quán)后, 開(kāi)發(fā)者可以通過(guò)自己的應(yīng)用把 client ID 當(dāng)做參數(shù)去請(qǐng)求一個(gè)令牌桨仿。在你的應(yīng)用程序 /oauth/authorize 的接口中應(yīng)該有一個(gè)重定向請(qǐng)求像下面這樣:
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'token',
'scope' => '',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
});
4.客戶端證書(shū)授權(quán)令牌
這是不需要登錄直接可以獲取token的方式睛低,用于機(jī)器與機(jī)器之前(app與服務(wù)端之間)
要使用這種授權(quán),你首先需要在 app/Http/Kernel.php 的 $routeMiddleware 變量中添加新的中間件:
use Laravel\Passport\Http\Middleware\CheckClientCredentials::class;
protected $routeMiddleware = [
'client' => CheckClientCredentials::class,
];
然后將這個(gè)中間件附加到路由中:
Route::get('/user', function(Request $request) {
...
})->middleware('client');
實(shí)際開(kāi)發(fā)中不可能給每個(gè)路由都這么分配蹬敲,我們可以在跟控制器中添加中間件:
function __construct()
{
$this->middleware('client');
}
要獲取令牌暇昂,向 oauth/token 接口發(fā)出請(qǐng)求:
Route::get('/get_token',function(){
$http = new GuzzleHttp\Client;
$response = $http->post(env('AUTH_HOST') . '/oauth/token', [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => '6',
'client_secret' => 'CfERioCd1lJcoKOiXGb5dXbkzXdB7VHnSMBCs3X6',
'scope' => '',
],
// 以json的格式返回報(bào)錯(cuò)信息
'http_errors' => false // add this to return errors in json
]);
return json_decode((string) $response->getBody(), true);
})
還有一個(gè)私人令牌這里沒(méi)有寫(xiě),有興趣的同學(xué)可以直接訪問(wèn)laravel5.5的文檔, 做個(gè)總結(jié)伴嗡,方便今后查閱急波。