php Laravel:生成随机唯一令牌

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33334927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:27:14  来源:igfitidea点击:

Laravel: Generate random unique token

phplaravellaravel-4laravel-5

提问by user5486944

I have a table in my database called keysthat has this structure:

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

id | user_id | token_id | token_key

Every time a user logs into my site, I need to generate a new token_idand token_keyset for that user. How can I generate a random token for both the token_idand the token_keywhile keeping the two values unique?

每次用户登录到我的网站,我需要生成一个新的token_id,并token_key为该用户设置。如何为 thetoken_id和 the生成随机令牌,token_key同时保持两个值的唯一性?

For example, if:

例如,如果:

  • token_idis dfbs98641aretwsg,
  • token_keyis sdf389dxbf1sdz51fga65dfg74asdf
  • token_iddfbs98641aretwsg
  • token_keysdf389dxbf1sdz51fga65dfg74asdf

Meaning:

意义:

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

There can be no other row in the table with that combination of tokens. How can I do this?

表中不能有具有该标记组合的其他行。我怎样才能做到这一点?

回答by James

In terms of generating the tokens, you could use one of Laravel's Helper Functions; str_random().

在生成令牌方面,您可以使用Laravel 的辅助函数之一str_random().

This will generate a random string of a specified length, e.g str_random(16)will generate a random string of 16 characters (upper case, lower case, and numbers).

这将生成一个指定长度的随机字符串,例如str_random(16)将生成一个 16 个字符(大写、小写和数字)的随机字符串。

Depending on how you are using the tokens, do they really need to be completely unique? Given that they will match to a user, or I assume you may be using the token_idand then verifying this against the token_keydoes it really matter if there is a double up of one of them? - although the chances of this are extremely small!

根据您使用令牌的方式,它们真的需要完全独一无二吗?鉴于它们将与用户匹配,或者我假设您可能正在使用token_id,然后根据 验证这token_key一点,如果其中一个加倍是否真的很重要?——虽然这种可能性极小!

However, if you do need them to be truly unique you can always use a validator with the uniqueconstraint. Using this packageyou could also test that the two of them are unique too with unique_with. And then if the validator fails then it generates a new token as needed.

但是,如果您确实需要它们真正独一无二,您始终可以使用带有unique约束的验证器。使用此包,您还可以使用unique_with. 然后,如果验证器失败,则它会根据需要生成一个新令牌。

Based off your examples, you would be using str_random(16)for token_idand str_random(30)for the token_key.

根据您的示例,您将使用str_random(16)fortoken_idstr_random(30)for token_key.

回答by Oliver Maksimovic

I'd avoid including an extra package for a case like this one. Something like:

我会避免为这样的案例包含一个额外的包。就像是:

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

...should do. Replace model name with yours, if different from 'User', and use your or suggested functions for creating random strings.

...应该做。如果与“用户”不同,请将模型名称替换为您的名称,并使用您或建议的函数来创建随机字符串。

回答by Yallison Gabriel Reis

You can use a dependency to do this. Dirape laravel-token

您可以使用依赖项来执行此操作。Dirape laravel-token

Run the command

运行命令

composer require dirape/token

In your controller use

在您的控制器中使用

use Dirape\Token\Token;

You can use it like this:

你可以这样使用它:

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

回答by daisura99

Following @ivanhoe suggestion... this is what I came up with:-

遵循@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) {

        }
    }