javascript - redis 中唯一、安全的短代码(使用 Node )

标签 javascript node.js asynchronous redis

我让用户使用他们提供的短代码访问 URL,例如example.com/ABCD。我正在运行 Node 并使用 node_redis 模块,尽管我认为这并不重要。生成唯一代码的安全方法是什么?

我可以随机生成一些东西并检查它是否在使用中,但是考虑到我对 redis 的调用的异步性质,它有可能在保存回 redis 之前在其他地方使用。

一些想法:

  • 我不担心有限的命名空间,如果需要我可以扩展它,但很可能不会
  • ...但是保持代码简短(易于在移动设备上输入)的目标意味着我希望保持命名空间较小,从而增加发生冲突的可能性。
  • 我想我可以在内存中保留已用(或未用)代码的列表,这不是最糟糕的事情,但似乎是一个奇怪的举动。
  • 我知道我可以让 redis 自动递增,但我不想使用数字(我不想连续)。

如果我不想将列表保存在内存中,我应该切换数据存储吗?我认为将列表保存在内存中是可以但不是很好的想法是否正确?

最佳答案

请参阅我 2013 年 7 月的回答:https://stackoverflow.com/a/17597649/1253312

为了安全起见,我会把它复制到这里:


实际上,我建议使用 Redis 来完成这项任务。它具有使此任务适合其使用的所有功能。最重要的是,它非常擅长在大列表中搜索值。

我们将创建两个列表,buffered_idsused_ids。 cronjob 将每 5 分钟(或您喜欢的任何时间间隔)运行一次,这将检查 buffered_ids 的长度并将其保持在 5000 以上的长度。当您需要使用一个 id 时,将其从 buffered_ids 中弹出并将其添加到 used_ids

Redis 有集合,它们是集合中的唯一项。将其视为一个散列,其中键是唯一的,所有值都是“真”。

你的 cronjob,在 bash 中:

log(){ local x=$1 n=2 l=-1;if [ "$2" != "" ];then n=$x;x=$2;fi;while((x));do let l+=1 x/=n;done;echo $l; }
scale=`redis-cli SCARD used_ids`
scale=`log 16 $scale`
scale=$[ scale + 6]
while [ `redis-cli SCARD buffered_ids` -lt 5000 ]; do
    uuid=`cat /dev/urandom | tr -cd "[:alnum:]" | head -c ${1:-$scale}`
    if [ `redis-cli SISMEMBER used_ids $uuid` == 1]; then
        continue
    fi
    redis-cli SADD buffered_ids $uuid
done

获取下一个 uid 用于您的应用程序(在伪代码中,因为您没有指定语言)

$uid = redis('SPOP buffered_ids');
redis('SADD used_ids ' . $uid);

编辑 实际上那里存在竞争条件。要安全地弹出一个值,请先将其添加到 used_ids,然后再将其从 buffered_ids 中删除。

$uid = redis('SRANDMEMBER buffered_ids');
redis('SADD used_ids ' . $uid);
redis('SREM buffered_ids ' . $uid);

关于javascript - redis 中唯一、安全的短代码(使用 Node ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23353879/

相关文章:

javascript - Node.js 拦截 Promise 并阐述 Response

javascript - lowdb 仅更新 JSON 文件中的一项信息

java - Spring @Async 不工作

asynchronous - f# 在 list.iteri 中执行 await 异步方法

javascript - Canvas 动画 - 基础知识

javascript - 如何通过按钮单击生成 FullCalendar

javascript - 查找并替换 Json 文件中的项目

javascript - Node js ajax 上缺少 Google 翻译键

node.js - Node.js async eachLimit 在这种情况下如何工作?

javascript - 在 ChartJS 中单击时如何获取条形图标签的值?