Laravel:生成随机唯一令牌

use*_*944 9 php laravel laravel-4 laravel-5

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

id | user_id | token_id | token_key
Run Code Online (Sandbox Code Playgroud)

每次用户登录我的网站时,我都需要为该用户生成一个新的token_idtoken_key设置.如何保持两个值唯一token_idtoken_key同时生成随机令牌?

例如,如果:

  • token_id是的dfbs98641aretwsg,
  • token_keysdf389dxbf1sdz51fga65dfg74asdf

含义:

id | user_id | token_id         | token_key
1  | 1       | dfbs98641aretwsg | sdf389dxbf1sdz51fga65dfg74asdf
Run Code Online (Sandbox Code Playgroud)

表中没有其他行与令牌组合.我怎样才能做到这一点?

Jam*_*mes 20

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

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

根据您使用令牌的方式,它们真的需要完全独特吗?鉴于它们将与用户匹配,或者我认为你可能正在使用它token_id然后验证这token_key是否真的重要,如果它们中的一个加倍? - 虽然这个机会非常小!

但是,如果确实需要它们才能真正独特,则可以始终使用带unique约束的验证器.使用这个软件包你也可以测试它们中的两个也是唯一的unique_with.然后,如果验证器失败,则根据需要生成新令牌.

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


Oli*_*vic 15

对于像这样的情况,我会避免包含额外的包裹.就像是:

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

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

  • 这是一个非常糟糕的解决方案!每次要添加新记录时,都不应该遍历数据库表中的每条记录.您最好使用基于时间的唯一字符串. (8认同)
  • 一种可能的改进是尝试插入新标记而不是选择它们.如果它们不是唯一的请求将失败(假设DB正确设置了唯一索引),并且您返回循环并创建一个新对并再次尝试直到操作成功.这将保证操作的原子性. (7认同)
  • 只要"while"中的语句评估为"true",[`do-while`](http://php.net/manual/en/control-structures.do.while.php)循环将保持"正在执行" (与'while-do`不同,它至少运行一次).在此特定示例中,它将生成令牌ID /密钥对,然后它将尝试在数据库中查找具有该特定令牌和密钥对的用户.`instanceof`检查结果是否是'User`类的实例,这意味着它正在检查是否找到了这样的用户.如果是,则`do`将再次执行并生成另一对,依此类推,直到找不到具有生成的令牌id /密钥对的用户. (4认同)
  • 每次添加新记录时,它都不会*遍历表中的每个*记录.请尝试理解`do-while`循环. (4认同)
  • 我同意@Marten。不是一个好的解决方案。它有两个问题:首先,您每次至少创建一次新令牌时都命中数据库-如果该令牌存在于数据库中,则再次命中它。第二,不能保证唯一性。在检查其存在之后以及将其插入当前线程之前,可以通过另一个线程将同一密钥插入db。为什么不使用在唯一性方面具有高度安全性的UUID? (2认同)