使用lumen進行api開發,實現api的鑑權,查找到的文檔基本上都是password的模式驗證,千篇一律,詳細如何請求,如何驗證都一筆跳過,本人在實踐過程中踩了不少坑,所以編寫此篇文章,希望其他同學勿再入同樣的坑。
一、安裝Lumen
composer create-project --prefer-dist laravel/laravel app_name
- 配置應用祕鑰
在App\Console\Commands下添加一下內容的KeyGenerateCommand.php文件
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class KeyGenerateCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'key:generate';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Set the application key';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$key = $this->generateRandomKey();
file_put_contents(base_path('.env'), preg_replace(
'/^APP_KEY=[\w]*/m',
'APP_KEY='.$key,
file_get_contents(base_path('.env'))
));
$this->info("Application key [$key] set successfully.");
}
/**
* Generate a random key for the application.
*
* @return string
*/
protected function generateRandomKey()
{
return str_random(32);
}
}
- 指令注入
// 修改App\Console下的Kernel.php
protected $commands = [
//注入指令
'App\Console\Commands\KenGenerateCommand',
]
- 控制檯執行密鑰生成命令
php artisan key:generate
二、安裝dingo
- 安裝dingo擴展
composer require dingo/api
- 註冊服務提供者
### bootstrap/app.php中註冊
$app->register(Dingo\Api\Provider\LumenServiceProvider::class);
### 具體配置以及多版本設置可參考Dingo API的官方文檔
https://learnku.com/docs/dingo-api/2.0.0/Installation/1443
- 創建路由
### 爲避免路由衝突,在router/web.php創建dingo/api的專屬路由
### 註冊實例
$api = app('Dingo\Api\Routing\Router')
### 使用$api接替原有的$router
### 如下路由
$api->version('v1', function($api) {
return response('this is version v1');
})
三、安裝Lumen-passport
- 安裝lumen-passport擴展
### 注意版本兼容
composer require dusterio/lumen-passport
- 修改bootstrap/app.php文件
<?php
// 取消如下配置的註釋
$app->withFacades();
$app->withEloquent();
$app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
// 加載配置文件config/auth.php
// 可將vendor/laravel/config文件夾複製到項目根目錄
$app->configure('auth');
// 開啓並修改默認認證中間件並增加client_credentials驗證的中間件
// 因爲本人使用了passport的client_credentials憑證
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
'client' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class
]);
// 新增passport註冊
$app->register(Laravel\Passport\PassportServiceProvider::class);
$app->register(Dusterio\LumenPassport\PassportServiceProvider::class);
- 修改auth.php配置
// 修改如下
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'passport-provider'
],
],
'providers' => [
'passport-provider' => [
'driver' => 'eloquent',
'model' => \App\User::class
]
],
- 增加HasApiTokens Trait 到user model
// lumen的默認路徑 app/user.php
/// 添加HasApiTokens
use Laravel\Passport\HasApiTokens;
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable, HasApiTokens;
}
四、創建數據表和客戶端
### 控制檯執行命令
### 創建數據表
php artisan migrate
### 創建客戶端
php artisan passport:client --client
### 會生成client_credentials的client_id和client_secret
五、獲取令牌Token
### 因passport自帶oauth路由,無需新建路由
### 獲取token,本人使用postman測試接口
### 請求url: 域名/oauth/token 請求方式: POST
### 注意:不能以參數的形式請求,應模擬表單提交,postman->body->x-www-form-urlencode
### 具體參數: client_id: 步驟四生成的client_id; client_secret:同上, grrant_type: client_credentials
### 返回結果:
{
"token_type": "Bearer",
"expires_in": 31622399,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjUwZWJiYWRhYzVjNTFmOTJiMzcwNGI5MjM0ODQxNWUzZDhiMzdiYmE1Nzk4ZmIxYmY4Y2VkODA1YmMwZGI4MTgxOGQ1ZTAwNTI3MjdjZWFhIn0.eyJhdWQiOiIzIiwianRpIjoiNTBlYmJhZGFjNWM1MWY5MmIzNzA0YjkyMzQ4NDE1ZTNkOGIzN2JiYTU3OThmYjFiZjhjZWQ4MDViYzBkYjgxODE4ZDVlMDA1MjcyN2NlYWEiLCJpYXQiOjE1Njk1NjQ3MjQsIm5iZiI6MTU2OTU2NDcyNCwiZXhwIjoxNjAxMTg3MTI0LCJzdWIiOiIiLCJzY29wZXMiOltdfQ.Kif33MaoPypJN2WNofILA2PKu_YsX7ArAzK9PCxksaiUrQHVUb5a9LdhBdvMLHaQ5gMn8KvkChKkG5xFWjI5Z8ARUEw7ucdYAW0-lfnxNvDf_Z9KOMdNZWXYYyY4t-4UYqhlRcZWclm4fEHkTWj60RLqYSlnArc0C6cKM_LYDjREHN1VJc_1hAN60uUgxBxAjLC5cMCtNlrZkrgm390UTPcUxTD_6N3a2wsLOKPJF9dz235WE_PZ2_SwMl-xaBQWgpu2pxFk1D8LSIB-q-v4eCJthXsWuTFmWJePr5Y8_hvV7Rlv-2y-4xYjt0okg_umcPputUixMunQ8nTYP2OI5DwO8veiaqrh87hsxeshvM4KXMiUgbgi73fLmS5uwhwVm-Klq4QZDJGcM6Vqj-CFwW3TAFbT0HimjZt5DiTgHdPpaTla6k4TO-ZV232HwnD1iyG90sCez2ZI2v4ab_RShGfvHh6njC_nfjEcaduweKVy2KJuYv_EvmVe94VKoYjC7MsUwm-OyNirvN3oGztvi6vnb2XGndLtmsEgmEJjD5l2oimKhKdEiinGW2RV7bindBpbI8d4Yx23yenz02pXiZHq4Rl6AJQq0kKOmnYATWVooEPJ-r051ykrcI8_VNSMC-wnr6E_iLou8jnbCUxBlwolUUBnZ7BOj5W5_Gt63Nc"
}
六、Token驗證
- 創建路由
$api->get('test', ['middleware' => 'client', function() use ($api) {
return response('auth success');
}]);
/*// 特別注意 //*/
/*// lumen中必須以此格式使用client的中間件 //*/
/*// 文檔中也沒說明,嘗試了好久發現 //*/
// 錯誤示範1:Undefined variable: closure 【報錯】
$api->get('test', ['middleware' => 'client'], function () {
return response('auth success');
});
// 錯誤示範2:middleware not exits 【報錯】
$api->get('test', function () {
return response('auth success');
})>middleware('client');
至此lumen的passport client_credentials憑證驗證基本完成。謹以此預防同我一樣入坑的同學