onursimsek/precondition

Laravel 的 HTTP 预条件实现

2.0.1 2024-05-18 14:39 UTC

This package is auto-updated.

Last update: 2024-09-11 11:32:52 UTC


README

Laravel 的 HTTP 预条件

Latest Version on Packagist MIT Licensed Tests Total Downloads

安装

要安装,请在您的项目中运行以下命令

composer require onursimsek/precondition

用法

客户端请求您的一个资源(GET),过了一会儿想要更新资源并发送回您(PUT)。与此同时,另一个客户端收到了相同的资源(GET)并在第一个客户端(PUT)之前更新了它。在这种情况下,第一个客户端的更新将基于一个错误的副本,并忽略第二个客户端的更新。这被称为 丢失更新问题

在这种情况下,您可以将 428 预先条件必须 返回给第一个客户端,并要求它再次拉取资源。

此包允许您轻松地做到这一点。您需要做的只是创建一个 验证器类,并将其作为 属性 添加到相应的控制器方法。

use Illuminate\Http\Request;
use OnurSimsek\Precondition\Validators\PreconditionValidator;

class LostUpdateValidator extends PreconditionValidator
{
    public function parameter(Request $request)
    {
        return $request->header('If-Unmodified-Since');
    }

    public function __invoke(Request $request): bool
    {
        return $this->parameter($request) == $request->route('article')->updated_at;
    }
}
use App\Models\Article;
use App\Http\Requests\UpdateArticleRequest;
use OnurSimsek\Precondition\Attributes\Precondition;

class ArticleController
{
    #[Precondition(LostUpdateValidator::class)]
    public function update(Article $article, UpdateArticleRequest $request)
    {
        $article->fill($request->validated())
        $article->save();

        return response()->json();
    }
}

最后,您需要将 预条件 中间件添加到您想要使用的 路由

Route::put('/articles/{:article}', [ArticleController::class, 'update'])
    ->middleware(['precondition']);

如果您有任何满足请求的条件,也可以使用此包。例如,以下是一些示例;

Github 示例

在删除仓库之前,您被提示重新输入仓库名称。

use Illuminate\Http\Request;
use OnurSimsek\Precondition\Validators\PreconditionValidator;

class DeleteRepositoryValidator extends PreconditionValidator
{
    public function parameter(Request $request)
    {
        return $request->input('repository_name');
    }

    public function __invoke(Request $request): bool
    {
        return $this->parameter($request) == $request->route('repository')->name;
    }
}

注意: 如果仓库名称无效,则响应返回状态码为 412 预先条件失败

SMS 验证

SMS 验证是支付流程中的强制步骤。

use Illuminate\Http\Request;
use OnurSimsek\Precondition\Validators\PreconditionValidator;

class SmsValidator extends PreconditionValidator
{
    public function preProcess(): void
    {
        cache()->set('sms', '123456');
    }

    public function parameter(Request $request)
    {
        return $request->input('sms_code');
    }

    public function __invoke(Request $request): bool
    {
        return $this->parameter($request) == cache()->get('sms');
    }
}

可选验证

如果您想逐个验证,可以使用以下方式使用 when 方法。

use Illuminate\Http\Request;
use OnurSimsek\Precondition\Validators\PreconditionValidator;

class PrivateArticleValidator extends PreconditionValidator
{
    public function when(Request $request) 
    {
        return $request->route('article')->is_private;
    }

    public function parameter(Request $request)
    {
        return $request->header('X-Article-Secret-Code');
    }

    public function __invoke(Request $request): bool
    {
        return $this->parameter($request) == $request->route('article')->secret_code;
    }
}

您可以在验证器类中使用 messages() 方法来自定义错误消息。

public function messages(): array
{
    return [
        'required' => 'Enter the sms code sent to your phone.',
        'failed' => 'Incorrect sms code!',
    ];
}

测试

composer test

变更日志

请参阅 CHANGELOG 了解最近更改的更多信息。

贡献

请参阅 CONTRIBUTING 了解详细信息。

安全漏洞

请参阅我们如何报告安全漏洞的 安全策略

致谢

许可证

MIT 许可证 (MIT)。请参阅 许可证文件 了解更多信息。