kiriunin / api-guard
使用Laravel通过API密钥验证API的简单方法
Requires
- php: >=7.2|>=8.0
- ellipsesynergie/api-response: *
- illuminate/database: ^5.5|^6.0|^7.0|^8.0
- illuminate/http: ^5.5|^6.0|^7.0|^8.0
- illuminate/support: ^5.5|^6.0|^7.0|^8.0
Requires (Dev)
- phpunit/phpunit: ^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0
This package is auto-updated.
Last update: 2024-09-28 18:10:51 UTC
README
使用Laravel通过API密钥验证API的简单方法。此包使用了以下库
- philsturgeon的 Fractal
- maximebeaudoin的 api-response
Laravel 5.3, 5.4和5.5现在终于支持了!
**Laravel 5.3.x及以后版本: ~4.*
**Laravel 5.1.x到5.2.x:~3.*
**Laravel 5.1.x:~2.*
**Laravel 4.2.x:~1.*(为Laravel 4最近更新的版本。请注意,这里有一些命名空间更改)
**Laravel 4.2.x:0.*(你们大多数人正在使用的版本)
快速入门
Laravel 5.3到5.4的安装
运行 composer require chrisbjr/api-guard 4.*
在你的 config/app.php 中,将 Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider 添加到 providers 数组的末尾
'providers' => array( ... Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider::class, ),
现在发布api-guard的迁移和配置文件
$ php artisan vendor:publish --provider="Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider"
然后运行迁移
$ php artisan migrate
这将设置 api_keys 表。
生成第一个API密钥
完成所需的设置后,你现在可以生成第一个API密钥。
运行以下命令以生成API密钥
php artisan api-key:generate
通常,ApiKey 对象是一个多态对象,这意味着它可以属于多个其他模型。
要生成一个与另一个对象(例如“用户”)相关联的API密钥,你可以执行以下操作
+php artisan api-key:generate --id=1 --type="App\User"
要指定模型可以具有API密钥,可以将Apikeyable特质附加到模型上
use Chrisbjr\ApiGuard\Models\Mixins\Apikeyable; class User extends Model { use Apikeyable; ... }
这将给模型附加以下方法
// Get the API keys of the object $user->apiKeys(); // Create an API key for the object $user->createApiKey();
要应用您的应用程序中生成API密钥,您可以在ApiKey模型中使用以下方法
$apiKey = Chrisbjr\ApiGuard\Models\ApiKey::make() // Attach a model to the API key $apiKey = Chrisbjr\ApiGuard\Models\ApiKey::make($model)
用法
您可以通过将auth.apikey中间件附加到API路由来开始使用ApiGuard
Route::middleware(['auth.apikey'])->get('/test', function (Request $request) { return $request->user(); // Returns the associated model to the API key });
这实际上通过需要指定在X-Authorization头中的API密钥来保护您的API。这可以在config/apiguard.php中进行配置。
以下是一个示例cURL命令以进行展示
curl -X GET \
http://apiguard.dev/api/test \
-H 'x-authorization: api-key-here'
您还可能想将此中间件附加到您的api中间件组中的app/Http/Kernel.php,以利用Laravel的其他功能,例如速率限制。
/** * The application's route middleware groups. * * @var array */ protected $middlewareGroups = [ ... 'api' => [ 'throttle:60,1', 'bindings', 'auth.apikey', ], ];
如果您注意到基本示例中,您还可以通过调用$request->user()来访问附加到API密钥的模型。我们在此方法中附加相关模型,因为在大多数用例中,这实际上是用户。
未经授权的请求
未经授权的请求将获得以下JSON的401状态响应
{
"error": {
"code": "401",
"http_code": "GEN-UNAUTHORIZED",
"message": "Unauthorized."
}
}
ApiGuardController
ApiGuardController利用了Fractal和api-response库。
这使得我们能够轻松创建具有模型的API,并使用转换器提供标准化的JSON响应。
以下是一个示例
假设你有一个以下模型
use Illuminate\Database\Eloquent\Model; class Book extends Model { protected $fillable = [ 'name', ]; }
你可以创建一个基本的控制器,它将返回所有书籍,如下所示
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController; use App\Transformers\BookTransformer; use App\Book; class BooksController extends ApiGuardController { public function all() { $books = Book::all(); return $this->response->withCollection($books, new BookTransformer); } }
现在,您需要为Book对象创建一个变压器。变压器有助于定义和操作您希望返回到JSON响应中的变量。
use League\Fractal\TransformerAbstract; use App\Book; class BookTransformer extends TransformerAbstract { public function transform(Book $book) { return [ 'id' => $book->id, 'name' => $book->name, 'created_at' => $book->created_at, 'updated_at' => $book->updated_at, ]; } }
一旦您在路由中可以访问它,您将收到控制器返回的以下响应
{
"data": {
"id": 1,
"title": "The Great Adventures of Chris",
"created_at": {
"date": "2017-05-25 18:54:18",
"timezone_type": 3,
"timezone": "UTC"
},
"updated_at": {
"date": "2017-05-25 18:54:18",
"timezone_type": 3,
"timezone": "UTC"
}
}
}
更多示例可以在GitHub页面找到: https://github.com/ellipsesynergie/api-response。
要了解更多关于变压器的信息,请访问PHP League的Fractal文档: Fractal
API验证响应
ApiGuard附带一个请求类,可以为您处理请求验证并抛出标准响应。
您可以根据通常的做法创建一个Request类,但为了获得标准的JSON响应,您需要扩展ApiGuardFormRequest类。
use Chrisbjr\ApiGuard\Http\Requests\ApiGuardFormRequest; class BookStoreRequest extends ApiGuardFormRequest { public function authorize() { return true; } public function rules() { return [ 'name' => 'required', ]; } }
现在您可以在控制器中使用它,就像您通常使用Laravel一样
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController; use App\Transformers\BookTransformer; use App\Book; class BooksController extends ApiGuardController { public function store(BookStoreRequest $request) { // Request should already be validated $book = Book::create($request->all()) return $this->response->withItem($book, new BookTransformer); } }
如果请求未能通过验证规则,它将返回以下类似的响应
{
"error": {
"code": "GEN-UNPROCESSABLE",
"http_code": 422,
"message": {
"name": [
"The name field is required."
]
}
}
}