Laravel:生成随机唯一令牌


Laravel: Generate random unique token

我的数据库中有一个名为keys的表,它具有以下结构:

id | user_id | token_id | token_key

每当用户登录到我的站点时,我需要为该用户生成一个新的token_idtoken_key集。如何为token_idtoken_key生成随机令牌,同时保持两个值唯一?

例如:

  • token_iddfbs98641aretwsg
  • token_key is sdf389dxbf1sdz51fga65dfg74asdf

的意义:

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());