touhidurabir/laravel-model-hashid

一个Laravel包,用于基于模型id列生成模型hashid。

1.1.0 2021-09-20 07:39 UTC

This package is auto-updated.

Last update: 2024-09-20 14:20:07 UTC


README

一个用于从Laravel模型的自动递增id生成模型hashid的包

安装

使用composer安装包

composer require touhidurabir/laravel-model-hashid

发布配置文件

php artisan vendor:publish --provider="Touhidurabir\ModelHashid\ModelHashidServiceProvider" --tag=config

它如何有帮助?

在开发公开API时,有时我们需要根据请求端点的给定模型id提供数据。例如

/some-end-point/some-model-resource/{id}

其中给定的 {id} 可以是模型表关联的自动递增id。使用 uuid 是另一种方法,现在这种方法相当流行,用于加密模型表的 id。例如

/some-end-point/some-model-resource/{uuid}

但是即使使用 uuid,我们也需要对查询进行调整,以基于uuid查找模型资源或将uuid作为模型的 主键

然而,这个包采用不同的方法,在模型资源创建时,它会生成并存储一个唯一的hashid,然后将其作为响应传递给远程请求。请求者使用这个hashid来向API发出请求,而不是id或uuid,但是通过中间件,这些hashid在路由参数或请求参数中解密为原始模型id。所以基本上是这样做

$id = 1;
$hashid = 'jRlef2';

当发出API请求时,如下所示

/some-end-point/some-model-resource/{hashid}

假设路由url指向某个控制器方法,那么

class SomeController extends Controller {

    public function show(int $id) {

        // $id where will be 1, not jRlef2
    }
}

配置选项

发布的配置文件包含一些可能的配置选项。请查看并阅读 config/hasher.php 以了解所有可能的选项。但其中一些重要选项是

启用

'enable' => env('ID_HASHING', false),

确定Hashid是否启用。默认设置为 true

密钥

'key' => env('ID_HASHING_KEY', ''),

使用此唯一密钥作为基础或盐值来生成hash。这不是必须的细节,但强烈建议在整个应用程序中使用一个唯一的密钥来使hashid更强大。

'column' => 'hash_id',

这定义了默认情况下此包应该查找的列以检索或存储生成的hashid。但仍然可能有一些列名称在这里,而在某些模型中有不同的名称。

字母表

'alphabets' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890',

这定义了hash字符串中唯一存在的字符。最好是使用广泛的字符集,默认为小写a-z、大写A-Z和0-9。

注意:它必须至少16个字符长,并且只能包含唯一字符。不允许重复,如'aaaabbbbbbcc'等。

regeneration_job

'regeneration_job' => \Touhidurabir\ModelHashid\Jobs\ModelHashidRegeneratorJob::class,

这定义了将用于运行更新或填充缺失hashid的作业,通过 hashid:run 命令。

命令

此包包含一个命令,可用于设置缺失的模型hashid或更新现有的一个。如果此包稍后添加到已经包含表中数据的任何Laravel应用程序中,并且需要为这些记录设置hashid,这将很有用。要使用此命令运行

php artisan hashid:run User,Profile

它需要一个 参数,即模型的名称命令(如果有多个模型要运行,请分隔)。在幕后,它调用队列作业遍历模型记录并处理它们以更新/填充hashid列值。其他选项如下

--path=

默认情况下,它假设所有模型都位于 App\Models\ 命名空间中。但如果它们位于其他位置,请使用选项来定义正确的模型空间路径,并使用 尾部斜杠

--update-all

默认情况下,此命令仅适用于具有定义的哈希ID列的空值的模型记录。因此,基本上它将填充缺失的项,但如果命令中提供了此false,则无论是否有关联哈希ID都会更新。

--on-job

这定义了是否通过队列工作更新/填充缺失的项。命令使用主逻辑所在的工作。但默认情况下,它使用框架提供的 dispatchNow 方法以同步方式运行作业。如果提供了标志且队列配置正确,则将作业推送到队列。

--job=

如果需要传递自定义队列工作实现,可以通过此选项直接提供。也可以在配置文件中更新队列类。

用法

在需要附加uuid的模型中使用特质 IdHashable

use Touhidurabir\ModelHashid\IdHashable;
use Illuminate\Database\Eloquent\Model;

class User extends Model {
    
    use IdHashable;
}

默认情况下,此包使用列名 hash_id 来存储模型自动递增ID的哈希值。但这是可以更改的

也可以覆盖uuid列并为每个模型附加事件。为此,需要在模型中放置以下方法

use Touhidurabir\ModelHashid\IdHashable;
use Illuminate\Database\Eloquent\Model;

class User extends Model {
    
    use IdHashable;

    /**
     * Get the name of hash column name
     *
     * @return string
     */
    public function getHashColumn() {

        return 'hash';
    }
}

现在要自动创建哈希路由或请求参数,请使用以下2个中间件

Touhidurabir\ModelHashid\Http\Middleware\DehashRequestParams // this to dehash request post/get params
Touhidurabir\ModelHashid\Http\Middleware\DehashRouteParams // this to dehash route hash params such as /{id} as hash

将这些中间件注册到 Http\Kernel.php 文件中或在控制器/路由文件中单独作为require。

注意DehashRequestParams 中间件只能解哈希字符串(简单哈希字符串)或数组(哈希字符串数组)的请求参数。因此,如果需要处理复杂参数,例如 JSON 字符串,则需要手动处理。

要处理此类情况,例如需要从JSON响应中解码某些键或出于其他目的进行手动解哈希,此包提供了2个辅助方法

  • decode_hashid
  • decode_hashids

如名称所示,decode_hashid 只能用于单个哈希,而 decode_hashids 可以用于单个哈希或哈希数组。

确保在迁移文件中将哈希ID列名放好

$table->string('hash_id')->nullable()->unique()->index();

或者可以与哈希器配置组合使用

$table->string(config('hasher.column'))->nullable()->unique()->index();

此包还包含一些辅助方法,可以轻松通过UUID查找模型记录。例如

User::byHashId($hash)->where('active', true)->first(); // single hash id
User::byHashId([$hash1, $hash2])->where('active', true)->get(); // multiple hash id

或简单直接查找

User::findByHashId($uhashuid); // single hash id
User::findByHashId([$hash1, $hash2]); // multiple hash id

此包还提供了一些安全措施,通过检查模型表是否有给定的哈希ID列。

如果模型表模式中没有找到哈希ID列,则不会创建和附加哈希ID。

额外功能

对于API资源

此包的一个大用途是在开发API服务时,开发人员不想包含模型原始的自增 id。在这种情况下,应使用 hash_id 如下

class User extends JsonResource {
    
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request) {

        return [
            'id'    => $this->hash_id,
            'email' => $this->email,
            ...
        ];
    }
}

上述方法完全可行。然而,由于哈希ID主要用于其他任何与模型相关的目的,因此可能希望将其隐藏

/**
 * The attributes that should be hidden for arrays.
 *
 * @var array
 */
protected $hidden = [
    'hash_id',
];

对于这种情况,此包包含一个简单的特质,可以与API资源类一起使用

use Touhidurabir\ModelHashid\IdHashing;

class User extends JsonResource {

    use IdHashing;
    
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request) {

        return [
            'id'    => $this->getId(),
            'email' => $this->email,
            ...
        ];
    }
}

使用核心Hasher类

本包的核心是处理整个哈希 解码/编码 过程的 Hasher 类。这高度依赖于流行的 php Hashid 包,并增加了一些额外功能。如果需要,也可以将此哈希器用于其他用途。要了解哈希器类的详细信息和工作原理,请查看 Touhidurabir\ModelHashid\Hasher\Hasher 中的代码。

贡献

欢迎提交 pull 请求。对于重大更改,请先创建一个问题以讨论您希望更改的内容。

请确保适当地更新测试。

许可证

MIT