2015-10-25 155 views
5

我有我的數據庫中的表稱爲keys具有這樣的結構:Laravel:隨機生成的唯一令牌

id | user_id | token_id | token_key 

每次用戶登錄到我的網站,我需要生成一個新的token_idtoken_key集該用戶。我如何爲token_idtoken_key生成一個隨機標記,同時保持這兩個值的唯一性?

例如,如果:

  • token_iddfbs98641aretwsg
  • token_keysdf389dxbf1sdz51fga65dfg74asdf

含義:

id | user_id | token_id   | token_key 
1 | 1  | dfbs98641aretwsg | sdf389dxbf1sdz51fga65dfg74asdf 

可以有在表中沒有其他行令牌的組合。我怎樣才能做到這一點?

回答

10

我會避免包括像這樣的情況下額外的軟件包。例如:

do { 
    $token_id = makeRandomToken(); 
    $token_key = makeRandomTokenKey(); 
} while (User::where("token_id", "=", $token_id)->where("token_key", "=", $token_key)->first() instanceof User); 

......應該做的。如果與「用戶」不同,請將模型名稱替換爲您的模型名稱,並使用您的或建議的函數來創建隨機字符串。

+0

你能解釋一下while循環將保證有贏沒有任何重複? – user5486944

+0

更具體地說,'instanceof'在while循環中做了什麼? – user5486944

+2

['do-while'](http://php.net/manual/en/control-structures.do.while.php)循環將保持「正在執行」,只要「while」中的語句評估爲「true」 '(和'while-do'不同,它至少運行一次)。在這個特定的例子中,它將生成令牌ID /密鑰對,然後它將嘗試在具有該特定令牌和密鑰對的數據庫中查找用戶。 'instanceof'檢查結果是否是'User'類的實例,意味着它檢查是否找到這樣的用戶。如果是,'do'將再次執行並創建另一個對,依此類推,直到找到沒有生成的令牌id/key對的用戶。 –

15

在生成令牌方面,您可以使用Laravel's Helper Functions之一; str_random()

這將生成一個指定長度的隨機字符串,例如str_random(16)將生成一個包含16個字符(大寫,小寫和數字)的隨機字符串。

根據你如何使用令牌,他們真的需要完全獨特嗎?鑑於它們將匹配用戶,或者我假設您可能正在使用token_id,然後根據token_key對此進行驗證,如果其中一個是雙倍的,它是否真的很重要? - 儘管這個機會非常小!

但是,如果你需要他們真正獨一無二的你可以隨時使用驗證與unique約束。使用this package您還可以測試其中的兩個是否也是唯一的unique_with。然後,如果驗證程序失敗,它會根據需要生成一個新的令牌。

基於關閉您的例子,你將使用str_random(16)token_idstr_random(30)token_key

0

您可以使用依賴關係來執行此操作。Dirape laravel-token

運行命令

composer require dirape/token 

在你的控制器使用

use Dirape\Token\Token; 

您可以使用它像這樣:

User::create([ 
     'name'    => $data['name'], 
     'email'   => $data['email'], 
     'password'   => bcrypt($data['password']), 
     'token_key' => (new Token())->Unique('users', 'api_token', 60), 
     'active'   => 1 
    ])