jwadhams/api-guard

此软件包已被放弃,不再维护。作者建议使用 laravel/sanctum 软件包代替。
此软件包最新版本(v6.0.2)没有可用的许可信息。

使用 Laravel 通过 API 密钥进行 API 认证的古老方法

v6.0.2 2020-09-29 01:49 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 认证的简单方法。此软件包使用以下库

支持矩阵

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 利用 Fractalapi-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."
      ]
    }
  }
}