vzool / api-hmac-guard
使用Laravel通过API HMAC密钥简单安全地验证API的简单方法
Requires
- php: >=5.6.4
- ellipsesynergie/api-response: *
- illuminate/database: ^5.3.0
- illuminate/support: ^5.3.0
Requires (Dev)
- phpunit/phpunit: ^4.0 || ^5.0
- dev-master
- v4.2.10
- v4.2.9
- v4.2.8
- v4.2.7
- v4.2.6
- v4.2.5
- v4.2.4
- v4.2.3
- v4.2.2
- v4.2.1
- v4.2
- v4.1.0
- v4.0.0
- 3.1.x-dev
- v3.1.2
- v3.1.1
- v3.1.0
- 3.0.x-dev
- v3.0.3
- v3.0.1
- v3.0.0
- v2.3.0
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.1
- v2.1.0
- v2.0.1
- v2.0.0
- 1.1.x-dev
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1
- v1.0
- v0.7
- v0.6
- v0.5
- v0.4
- v0.3
- v0.2
- v0.1
- dev-develop
This package is auto-updated.
Last update: 2024-09-06 23:51:53 UTC
README
使用Laravel通过API HMAC密钥简单安全地验证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.*
(你们大多数人使用的版本)
分支概述要点
1- API令牌绝不应存储在数据库中,这有助于我们保护用户令牌,防止在发生数据泄露时通过泄露的数据库令牌冒充用户账户。
2- 数据库将保存一个public_key
,这是一个访问密钥对记录的端点,此密钥应该是唯一的并建立索引。
3- 数据库将保存一个private_key
,该密钥将在服务器端保持私密。
4- 每次请求发生时,都会生成一个作为shared_key
的令牌。
5- 令牌将通过Hmac生成,并使用应用程序密钥config('app.key')
作为服务器私钥,与private_key
一起,在服务器端被视为客户端私钥。
6- 默认的Hmac算法是sha3-384
,有许多算法可供选择这里。
7- 如果您更改Hmac算法,密钥长度将不同,这取决于算法本身。
8- Middleware
将期望作为标题的两个密钥,它们是
X-Auth-EndPoint
:这是一个public_key
X-Auth-Token
:这是一个shared_key
9- 如果您不喜欢默认的标题名称,则可以从中更新它们apiguard.php
配置文件。
10- 您应该将这些两个密钥public_key
和shared_key
发送给您的客户端,并让他们将其发送回服务器以进行身份验证。
快速示例
>>> $key = ApiKey::make($person); // or $user => Vzool\ApiHmacGuard\Models\ApiKey {#1256 public_key: "-15af2b946b069d-5mQykkuMmF8UDZIuZkG8AdFfB3udhYkGW-", apikeyable_id: 1, apikeyable_type: "App\Models\Person", last_ip_address: "127.0.0.1", last_used_at: Carbon\Carbon @1525856582 {#1263 date: 2018-05-09 12:03:02.723851 Asia/Riyadh (+03:00), }, private_key: "-17AKPqotjcQBjzmdktluKiR5qUbyyzqWov-15af2b946b0c4-", updated_at: "2018-05-09 12:03:02", created_at: "2018-05-09 12:03:02", id: 5, } >>> $key->clientKeys() => [ "endpoint" => "-15af2b946b069d-5mQykkuMmF8UDZIuZkG8AdFfB3udhYkGW-", "token" => "9f9de38c4405a747fc25dd146b2ee6a30e8ea627c7da26d5a616c4c2fcb9ec896b4020febcb4971a65b97959c5d5625a", ] >>> >>> $key->publicKey() => "-15af2b946b069d-5mQykkuMmF8UDZIuZkG8AdFfB3udhYkGW-" >>> $key->sharedKey() => "9f9de38c4405a747fc25dd146b2ee6a30e8ea627c7da26d5a616c4c2fcb9ec896b4020febcb4971a65b97959c5d5625a" >>> $key->privateKey() => null // private keys are always protected and writable for one time
快速开始
Laravel 5.3到5.4的安装
运行composer require vzool/api-hmac-guard 4.*
在您的config/app.php
中,将Vzool\ApiHmacGuard\Providers\ApiGuardServiceProvider
添加到providers
数组末尾
'providers' => array( ... Vzool\ApiHmacGuard\Providers\ApiGuardServiceProvider::class, ),
现在发布api-guard的迁移和配置文件
$ php artisan vendor:publish --provider="Vzool\ApiHmacGuard\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 Vzool\ApiHmacGuard\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 = Vzool\ApiHmacGuard\Models\ApiKey::make() // Attach a model to the API key $apiKey = Vzool\ApiHmacGuard\Models\ApiKey::make($model)
访问客户端密钥
$apiKey->clientKeys()
用法
您只需将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'
您还可能希望将此中间件附加到您的app/Http/Kernel.php
中的api
中间件组中,以利用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库。
这使我们能够轻松创建带有模型和使用转换器以提供标准化JSON响应的API。
以下是一个示例
假设您有以下模型
use Illuminate\Database\Eloquent\Model; class Book extends Model { protected $fillable = [ 'name', ]; }
您可以创建一个基本的控制器,它将返回所有书籍,如下所示
use Vzool\ApiHmacGuard\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](https://github.com/ellipsesynergie/api-response)
要了解更多关于转换器的信息,请访问PHP League关于Fractal的文档:[http://fractal.thephpleague.com/](http://fractal.thephpleague.com/)
API验证响应
ApiGuard附带一个请求类,可以为您处理请求验证并抛出标准响应。
您可以像平常一样创建一个Request
类,但要获得标准JSON响应,您必须扩展ApiGuardFormRequest
类。
use Vzool\ApiHmacGuard\Http\Requests\ApiGuardFormRequest; class BookStoreRequest extends ApiGuardFormRequest { public function authorize() { return true; } public function rules() { return [ 'name' => 'required', ]; } }
现在您可以在控制器中使用它,就像您通常在Laravel中那样
use Vzool\ApiHmacGuard\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." ] } } }