swiftmade/playback

在 Laravel 中实现 Stripe 风格的幂等端点

v1.0.0 2022-07-29 14:35 UTC

This package is not auto-updated.

Last update: 2024-09-21 00:44:48 UTC


README

Latest Version on Packagist GitHub Actions Total Downloads

Laravel 中的幂等端点类似于 Stripe。

Playback 通过 Redis 锁在 Laravel 中提供幂等端点。 什么是幂等性,为什么我应该关心?

特性

  • 📼 记录并回放 2xx 和 5xx 响应,无需再次运行控制器代码。
  • 🔐 内置验证以防止使用被盗/猜测的幂等性键的攻击。
  • ⚠️ 如果存在验证错误(4xx),则不会存储响应。
  • 🏎 使用原子 Redis 锁防止竞争条件。

安装

💡 支持 Laravel 8.x、Laravel 9.x,在 PHP 7.4、8.0 或 8.1 上

  1. 您可以通过 composer 安装此包
composer require swiftmade/playback
  1. 发布配置文件(可选)
php artisan vendor:publish --provider="Swiftmade\Playback\PlaybackServiceProvider"
  1. 添加 playback 缓存存储

打开 config/cache.php 并添加一个新的存储。

'stores' => [
    // ... other stores
    'playback' => [
        'driver' => 'redis',
        // 👇🏻 Caution!
        // You probably don't want to use the cache connection in production.
        // Playback cache can grow to a big size for busy applications.
        // Make sure your redis instance is ready.
        'connection' => 'cache',
    ],
]

💡 应用中间件

只需将 Swiftmade\Playback\Playback 中间件应用到您的端点。有很多种方法可以做到这一点,所以这里有一个链接到文档

使用

即使中间件在路由上处于活动状态,除非客户端在请求头中发送 Idempotency-Key,否则一切照旧。

Idempotency-Key: preferrably uuid4, but anything flies

一旦 Playback 检测到密钥,它将在 Redis 中查找。如果找到,它将提供相同的响应 而无需再次调用控制器操作。您可以通过查看响应头来知道发生了什么。如果它包含 Is-Playback,则知道它只是重复。

如果在查找过程中未找到密钥,则开始竞争。第一个请求获得 Redis 锁以处理请求并缓存响应。在此时间窗口内到达的其他任何不幸请求都将返回 425 状态码。

错误

  • 400 错误请求 如果您收到状态 400 的响应,这意味着您的请求与缓存的请求不匹配。这是客户端的责任重复完全相同的请求。这也是为什么另一个用户不能通过窃取/猜测幂等性密钥来窃取响应。cookies/身份验证令牌将不同,这会导致签名检查失败。

  • 425 过早 如果您收到此错误,这意味着您在初次尝试后重试得太快。不要慌张,稍后再试一次。这是完全可以接受的!

🚨 高级技巧:如果您的控制器操作返回 4xx 或 3xx 状态码,Playback 不会缓存响应。确保在没有验证失败(或相关数据库记录未找到等)导致响应状态为 4xx 或 3xx 的情况下没有副作用发生(或它们被回滚)是您的责任。

测试

composer test

变更日志

请参阅 变更日志 了解最近更改的更多信息。

贡献

请参阅 贡献 了解详细信息。

安全性

如果您发现任何安全问题,请通过电子邮件 hello@swiftmade.co 而不是使用问题跟踪器。

致谢

许可证

MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件