balping / laravel-hashslug
提供在模型上使用Hashids功能的特质
Requires
- hashids/hashids: ^3.0|^4.0|^5.0
- illuminate/database: ^8.0|^9.0|^10.0|^11.0
- illuminate/routing: ^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^8.0
- phpunit/phpunit: ^10.0|^11.0
README
此包可用于使用Hashids隐藏真实模型ID以在URL中。给定应用、模型类和ID,哈希ID(短名)是确定性地生成的。另外,给定一个哈希ID(短名),也可以解码出真实ID。因此,不需要在数据库中存储额外的字段,ID在每次请求时进行解码。
动态生成URL
database -> id (1) -> hashslug (K4Nkd) -> url (http://localhost/posts/K4Nkd)
动态解码哈希ID并查找模型
url (http://localhost/posts/K4Nkd) -> hashslug (K4Nkd) -> id (1) -> database -> model
Hashslugs具有以下属性
- 保证hashslugs对于每个ID是唯一的
- 保证对于不同的模型,生成的哈希slug序列是不同的(ID为1的帖子将具有与ID为1的评论不同的hashslug)
- 保证对于不同的安装,生成的哈希slug序列是不同的(取决于.env文件中的app key)
需要注意的是,hashids不是随机的,也不是不可预测的。如果这成为问题,请不要使用此包。引用自hashids.org
如果你有一个关于“安全性”和“hashids”的问题或评论,请不要使用Hashids。
然而,虽然hashslug编码依赖于app key,但攻击者无法暴露它,因为它在传递给Hashids之前被sha256散列。你的app key是安全的。
安装
composer require balping/laravel-hashslug
版本
Laravel | Hashslug |
---|---|
5.4.* | 2.0.* |
5.5 - 5.8 | 2.1.* |
6.* | 2.1.* |
7.* | 2.2.* |
8.* | 2.3.* |
9.* | 2.3.* |
10.* | 2.3.* |
11.* | 2.3.* |
注意:此包需要PHP的
BC Math
或GMP
扩展才能工作。
用法
在希望具有哈希ID短名的模型上包含特质以隐藏数值递增ID。
use Illuminate\Database\Eloquent\Model;
use Balping\HashSlug\HasHashSlug;
class Post extends Model {
use HasHashSlug;
}
之后,模型将添加slug()
、findBySlug($slug)
和findBySlugOrFail($slug)
函数。
每次使用Laravel的帮助器生成URL时,都会使用哈希ID(默认长度为5个字符)而不是数值ID。
// routes/web.php
Route::resource('/posts', 'PostController');
// somewhere else
$post = Post::first();
echo action('PostController@show', $post);
// prints http://localhost/posts/K4Nkd
然后你可以通过短名解析模型。
// app/Http/Controllers/PostController.php
public function show($slug){
$post = Post:findBySlugOrFail($slug);
return view('post.show', compact('post'));
}
你还可以使用隐式模型绑定。你什么都不用做,它会自动工作!
只需输入模型类型提示,它们就会自动解析
// routes/web.php
Route::resource('/posts', 'PostController');
// app/Http/Controllers/PostController.php
public function show(Post $post){
return view('post.show', compact('post'));
}
如果你需要显式模型绑定,这也是方便的
//app/Providers/RouteServiceProvider.php
public function boot(){
parent::boot();
Route::model('article', App\Post::class);
}
// routes/web.php
Route::resource('/articles', 'PostController');
// app/Http/Controllers/PostController.php
public function show(Post $post){
return view('post.show', compact('post'));
}
URL中使用常规ID的用法
如果你想避免使用hashslug的隐式或显式模型绑定,并希望使用常规ID作为默认键,这也是可能的
// routes/web.php
Route::resource('/posts', 'PostController')->parameters([
"posts" => "post:id"
]);
// or
Route::get('/posts/{post:id}', [PostController::class, 'show']);
// get URL
action('PostController@show', $post);
// app/Http/Controllers/PostController.php
public function show(Post $post){
return view('post.show', compact('post'));
}
如果你在控制器中没有使用类型提示
// routes/web.php
Route::resource('/posts', 'PostController');
// or
Route::get('/posts/{id}', [PostController::class, 'show']);
// get URL
action('PostController@show', $post->id);
// app/Http/Controllers/PostController.php
public function show($post_id){
$post = Post::findOrFail($post_id);
}
作为替代,你可以重写以下两个方法来实现相同的效果并回退到常规ID
class Post extends Model {
use HasHashSlug;
public function getRouteKeyName(){
return parent::getRouteKeyName();
}
public function getRouteKey(){
return parent::getRouteKey();
}
}
自定义
盐
哈希slug序列在每个模型和应用程序安装中的唯一性取决于拥有唯一的盐。
默认情况下,传递给Hashids的盐取决于.env文件中定义的应用程序key和模型的类名。
应用程序盐
要更改“应用程序盐”,创建文件config/hashslug.php
然后添加以下代码
<?php
return [
'appsalt' => 'your-application-salt'
];
请注意,您不需要配置此功能,但如果您不进行配置并且更改了您的应用程序密钥,则包含hashslugs的每个URL都将更改。例如,如果用户将此类URL设为书签,这可能会成为一个问题。
模型盐值
要使用自定义模型盐值而不是类名
class Post extends Model {
use HasHashSlug;
protected static $modelSalt = "posts";
}
如果您有多个同一模型的扩展类并且需要hashslugs保持一致,这样做可能是个好主意。
填充
更改slug的最小长度(默认:5)
class Post extends Model {
use HasHashSlug;
protected static $minSlugLength = 10;
}
您还可以通过将以下行添加到 config/hashslug.php
来全局设置slug的最小长度
'minSlugLength' => 10
字母表
默认的字母表是 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
这可以更改
class Post extends Model {
use HasHashSlug;
protected static $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
您还可以通过将以下行添加到 config/hashslug.php
来全局设置字母表
'alphabet' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
前缀
您可以设置hashslug的自定义前缀
class Post extends Model {
use HasHashSlug;
protected static $hashSlugPrefix = 'post-';
}
这将返回形如 post-K4Nkd
的slug。
类似包及其区别
Laravel Hashids
提供一个外观,但没有内置路由。通过“连接”允许使用多个盐值。如果只需要为slugging模型使用hashids,则这是不必要的开销。
Eloquent-Hashids
在功能上与这个包基本相同,但使用上面的包会添加一个不必要的复杂层。使使用路由绑定成为可选的。
Laravel-Hashid
提供一个外观,类似于上面的外观,还提供一个类似这个包的特质。没有内置路由。没有提供测试。如果只需要为slugging模型使用hashids,则这是不必要的开销。
Hashids for Laravel 5
仅提供外观。不如第一个好,因为它只能有一个盐值。
Optimus
使用不同的混淆方法。仅提供外观(和类)。与路由或模型特质无关。据说它比hashids更快。
Laravel FakeID
类似于这个包,但基于Optimus构建。提供外观、特质以及特殊的路由功能。有良好的测试。
许可
这个包(特性和测试文件)在GPLv3许可下。