Model保留ID的情況下對外提供UUID

Model保留ID的情況下對外提供UUID

在某些應用程序中,不暴露 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 IlluminateSupportFacadesSchema; use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseMigrationsMigration; 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

你可能會爭辯說 另外一個索引會妨礙插入操作,但是這是一個權衡。

現在,問題在于控制器和模型。

將模型連接至 UUID

你不需要在模型中做任何事,除了兩件事:將 ID 從序列化中隱藏,并允許模型使用 UUID 進行「 URL 路由」。

<?php namespace App; use IlluminateDatabaseEloquentModel; 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  AppPodcast $podcast  * @return IlluminateHttpResponse /*  public function show(Podcast $podcast) {     return response()->view('response', [         'podcast' => $podcast     ]); }

你也可以使用模型中的 resolveRouteBinding() 方法,你是否可以以編程的方式設置如何通過給定值來檢索模型。你甚至可以允許經過身份驗證的管理員根據記錄的 ID 或者 UUID 來獲取記錄。

就這樣,沒什么可做的了。該技術還允許在 應用程序生成后 設置 UUID 。

更多Laravel相關技術文章,請訪問Laravel教程欄目進行學習!

? 版權聲明
THE END
喜歡就支持一下吧
點贊13 分享