在某些應用程式中,不暴露 ID 可以避免別人輕易得知你資料庫裡模型的數量。
譯者註:隱藏 ID 也可有效防止使用者惡意遍歷網站的內容。
嘿, 想像一下,在我的Podcast 應用程式中,我設定了一個預設id 在Laravel 的Podcast 模型中,它是一個整數,每次插入一行時都會自動增加一個,因此表中的第47個Podcast 的id 為47。然後我在我的網站內聲稱:“這個Podcast 應用程式擁有數百萬個播客,所以千萬不要錯過!”,在看到最新播客ID 時很容易被揭穿:
https://podcast.app/podcasts/47
在不需要重新連接應用程式中的所有內容的情況下隱藏ID,並且希望不被識破?好的,有方法。
有些資料庫可以設定為在插入新行時將 UUID 設定為主鍵。你應該在正在使用的 RDBMS 上檢查這一點,因為每個 RDBMS 的實作都有所不同。
你也可以告訴應用程式在使用 建立 Eloqument 事件新紀錄時設定預設 UUID ,但這將使你在任何情況下都得使用 Eloqument 。如果你直接向資料庫插入一筆記錄,你可能會得到一個錯誤——這也是我喜歡在資料庫中設定自動UUID 而不是應用程式的原因之一,它不應該依賴任何東西,因為這是資料庫行為。
總之,你應該像這樣使用Laravel 設定你的資料庫:
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreatePodcastTable extends Migration { /** * 运行数据库迁移 * * @return void */ public function up() { Schema::create('podcast', function (Blueprint $table) { $table->bigIncrements('id'); $table->uuid('uuid')->index(); $table->string('filename'); $table->string('path'); $table->string('service'); $table->string('format', 4); $table->unsginedTinyInteger('quality', 4); $table->timestamps(); $table->timestamps(); $table->softDeletes(); }); } /** * 回滚数据库迁移 * * @return void */ public function down() { Schema::dropIfExists('podcast'); } }
如你所看到的,我們增加了$table->uuid('uuid')- >index()
。這段程式碼告訴Laravel 去使用UUID 這一列(如果支持,或者使用字串列),並在這一列上建立索引,這樣就可以透過UUID 快速檢索行,就像有人訪問這個URL 時所做的那樣:
https://podcast.app/podcast/535c4cdf-70a0-4615-82f2-443e95c86aec
你可能會爭辯說另外一個索引會妨礙插入操作,但是這是一個權衡。
現在,問題在於控制器和模型。
你不需要在模型中做任何事,除了兩件事:將ID 從序列化中隱藏,並允許模型使用UUID 進行「 URL 路由」 。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Podcast extends Model { /** * 数组中隐藏的属性 * * @var array */ protected $hidden = [ 'id' ]; /** * 获取模型的路由键 * * @return string */ public function getRouteKeyName() { return 'uuid'; } // ……其余的模型代码 }
要隱藏 ID ,我們可以將 id
欄位新增至隱藏屬性數組。當模型被序列化時,例如轉換為陣列或 JSON 字串時,將不會顯示 ID 。當然,你也可以像存取屬性或陣列鍵那樣存取所獲得的屬性的 ID。
下一步告訴 Laravel ,當 URL 包含模型的 UUID 時,則透過 uuid
欄位來取得模型。這將允許透過設定一個路由來尋找模型,例如:
Route::get({podcast}, 'PodcastController@show');
然後在我們的 PodcastController
類別中使用它。
/** * 通过 UUID 显示播客 * * @param \App\Podcast $podcast * @return \Illuminate\Http\Response /* public function show(Podcast $podcast) { return response()->view('response', [ 'podcast' => $podcast ]); }
你也可以使用模型中的 resolveRouteBinding() 方法,你是否可以以程式設計的方式設定如何透過給定值來檢索模型。你甚至可以允許經過驗證的管理員根據記錄的 ID 或 UUID 來取得記錄。
就這樣,沒什麼好做的了。該技術還允許在 應用程式生成後 設定 UUID 。
更多Laravel相關技術文章,請造訪Laravel教學專欄進行學習!
以上是Model保留ID的情況下對外提供UUID的詳細內容。更多資訊請關注PHP中文網其他相關文章!