我的数据库中有一个名为keys
的表,它具有以下结构:
id | user_id | token_id | token_key
每当用户登录到我的站点时,我需要为该用户生成一个新的token_id
和token_key
集。如何为token_id
和token_key
生成随机令牌,同时保持两个值唯一?
例如:
-
token_id
是dfbs98641aretwsg
, -
token_key
issdf389dxbf1sdz51fga65dfg74asdf
的意义:
id | user_id | token_id | token_key
1 | 1 | dfbs98641aretwsg | sdf389dxbf1sdz51fga65dfg74asdf
表中不能有其他行具有该令牌组合。我该怎么做呢?
在生成令牌方面,您可以使用Laravel的Helper函数之一;str_random()
.
这将生成一个指定长度的随机字符串,例如str_random(16)
将生成一个16个字符(大写,小写和数字)的随机字符串。
根据您使用令牌的方式,它们真的需要完全唯一吗?考虑到它们将与用户匹配,或者我假设您可能使用token_id
,然后针对token_key
验证这一点,如果其中一个存在双重问题真的很重要吗?-尽管这种可能性非常小!
但是,如果您确实需要它们是真正唯一的,您可以始终使用具有unique
约束的验证器。使用这个包,您还可以在unique_with
中测试它们两个是否唯一。如果验证器失败,它会根据需要生成一个新的令牌。
根据您的示例,您将str_random(16)
用于token_id
, str_random(30)
用于token_key
。
对于这种情况,我会避免包含额外的包。比如:
do {
$token_id = makeRandomToken();
$token_key = makeRandomTokenKey();
} while (User::where("token_id", "=", $token_id)->where("token_key", "=", $token_key)->first() instanceof User);
…应该做的。将模型名替换为您的模型名,如果与'User'不同,并使用您的或建议的函数来创建随机字符串。
您可以使用依赖项来完成此操作。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
])
按照@ivanhoe的建议…这就是我想出来的:-
$token = new Token;
//in case there are duplicate
for ($x = 0; $x < 10; $x ++) {
$token->access_token = str_random(16);;
try {
if ($token->save()) {
break;
}
}catch (QueryException $e) {
}
}
其他看到这篇文章的用户。我找到的最佳解决方案是使用另一个字符串或整数来制作令牌。例如,当创建一个新用户时,laravel在做什么?
base64_encode($data['email']); // here using the email as base
我觉得这样比较好:
do {
$this->slug = strtolower(str()->random(5));
} while (User::where("slug", $this->slug)->exists());