jwadhams / api-guard
使用 Laravel 通过 API 密钥进行 API 认证的古老方法
Requires
- php: >=7.2
- ellipsesynergie/api-response: *
- illuminate/database: ^6.0
- illuminate/support: ^6.0
Requires (Dev)
- phpunit/phpunit: ^8.0
This package is auto-updated.
Last update: 2020-09-30 18:13:19 UTC
README
历史
此软件包是基于 chrisbjr/api-guard 的分支,旨在为 Laravel 6 和 7 提供一些向前支持,以帮助想要迁移到 Laravel Sanctum 的人。
如果您打算在 2020 年首次下载它,请三思。
Laravel 自 Laravel 5.8 和 Laravel 6.x 以来已内置类似功能。有关 Laravel 的 API 认证文档,请参阅 此处。此外,自 Laravel 7.x 以来,有一个新的 Laravel 软件包名为 Airlock/Sanctum,更适合 API 认证目的。
使用 Laravel 通过 API 密钥进行 API 认证的简单方法。此软件包使用以下库
- philsturgeon 的 Fractal
- maximebeaudoin 的 api-response
支持矩阵
Laravel 版本 | api-guard 版本 |
---|---|
6.x | ^6.* |
5.3 及以上 | ~4.* |
5.1.x 到 5.2.x | ~3.* |
快速入门
安装
运行 composer require JWadhams/api-guard
在 config/app.php
中,将 JWadhams\ApiGuard\Providers\ApiGuardServiceProvider
添加到 providers
数组的末尾
'providers' => array( ... JWadhams\ApiGuard\Providers\ApiGuardServiceProvider::class, ),
现在发布 api-guard 的迁移和配置文件
$ php artisan vendor:publish --provider="JWadhams\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 JWadhams\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 = JWadhams\ApiGuard\Models\ApiKey::make() // Attach a model to the API key $apiKey = JWadhams\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 });
这实际上使用 API 密钥保护了您的 API,需要在 X-Authorization
标头中指定。这可以在 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 JWadhams\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 JWadhams\ApiGuard\Http\Requests\ApiGuardFormRequest; class BookStoreRequest extends ApiGuardFormRequest { public function authorize() { return true; } public function rules() { return [ 'name' => 'required', ]; } }
现在您可以在控制器中使用它,就像您通常使用 Laravel 一样
use JWadhams\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." ] } } }