329

この質問では、Erik は Node.js で安全なランダム トークンを生成する必要があります。crypto.randomBytesランダムな Buffer を生成するメソッドがあります。ただし、ノードの base64 エンコーディングは URL セーフではなく、 /and+の代わりに-andが含まれ_ます。したがって、私が見つけたそのようなトークンを生成する最も簡単な方法は

require('crypto').randomBytes(48, function(ex, buf) {
    token = buf.toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
});

もっとエレガントな方法はありますか?

4

14 に答える 14

427

crypto.randomBytes()を試してください:

require('crypto').randomBytes(48, function(err, buffer) {
  var token = buffer.toString('hex');
});

'hex'エンコーディングは、ノードv0.6.x以降で機能します。

于 2012-01-13T19:33:12.227 に答える
289

あなたが私のようなJSの専門家でない場合の同期オプション。インライン関数変数にアクセスする方法に時間を費やす必要がありました

var token = crypto.randomBytes(64).toString('hex');
于 2014-08-13T16:59:27.257 に答える
102

1. nanoid サードパーティ ライブラリの使用 [NEW!]


JavaScript 用の小さくて安全な URL フレンドリーな一意の文字列 ID ジェネレーター

https://github.com/ai/nanoid

import { nanoid } from "nanoid";
const id = nanoid(48);

2. URL およびファイル名セーフ アルファベットを使用した Base 64 エンコーディング


RCF 4648 の 7 ページには、URL の安全性を備えた Base 64 でエンコードする方法が記載されています。base64urlのような既存のライブラリを使用してジョブを実行できます。

関数は次のようになります。

var crypto = require('crypto');
var base64url = require('base64url');

/** Sync */
function randomStringAsBase64Url(size) {
  return base64url(crypto.randomBytes(size));
}

使用例:

randomStringAsBase64Url(20);
// Returns 'AXSGpLVjne_f7w5Xg-fWdoBwbfs' which is 27 characters length.

返される文字列の長さが size 引数と一致しないことに注意してください (size != 最終的な長さ)。


3. 限られた文字セットからの暗号ランダム値


このソリューションでは、生成されたランダム文字列が均一に分散されないことに注意してください。

次のような限られた文字セットから強力なランダム文字列を作成することもできます。

var crypto = require('crypto');

/** Sync */
function randomString(length, chars) {
  if (!chars) {
    throw new Error('Argument \'chars\' is undefined');
  }

  const charsLength = chars.length;
  if (charsLength > 256) {
    throw new Error('Argument \'chars\' should not have more than 256 characters'
      + ', otherwise unpredictability will be broken');
  }

  const randomBytes = crypto.randomBytes(length);
  let result = new Array(length);

  let cursor = 0;
  for (let i = 0; i < length; i++) {
    cursor += randomBytes[i];
    result[i] = chars[cursor % charsLength];
  }

  return result.join('');
}

/** Sync */
function randomAsciiString(length) {
  return randomString(length,
    'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
}

使用例:

randomAsciiString(20);
// Returns 'rmRptK5niTSey7NlDk5y' which is 20 characters length.

randomString(20, 'ABCDEFG');
// Returns 'CCBAAGDGBBEGBDBECDCE' which is 20 characters length.
于 2014-09-05T17:04:28.627 に答える
21

async と await の ES 2016 標準を使用してこれを非同期的に行う最新の正しい方法(ノード 7 の時点) は次のようになります。

const crypto = require('crypto');

function generateToken({ stringBase = 'base64', byteLength = 48 } = {}) {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(byteLength, (err, buffer) => {
      if (err) {
        reject(err);
      } else {
        resolve(buffer.toString(stringBase));
      }
    });
  });
}

async function handler(req, res) {
   // default token length
   const newToken = await generateToken();
   console.log('newToken', newToken);

   // pass in parameters - adjust byte length
   const shortToken = await generateToken({byteLength: 20});
   console.log('newToken', shortToken);
}

これは、Babel 変換なしで Node 7 ですぐに使用できます。

于 2017-05-09T10:10:44.383 に答える
12

ランダムな URL とファイル名の文字列は安全 (1 ライナー)

Crypto.randomBytes(48).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
于 2016-03-15T10:34:22.590 に答える
4

real_atesES2016 の方法を見てください。より正確です 。

ECMAScript 2016 (ES7) の方法

import crypto from 'crypto';

function spawnTokenBuf() {
    return function(callback) {
        crypto.randomBytes(48, callback);
    };
}

async function() {
    console.log((await spawnTokenBuf()).toString('base64'));
};

ジェネレーター/イールドウェイ

var crypto = require('crypto');
var co = require('co');

function spawnTokenBuf() {
    return function(callback) {
        crypto.randomBytes(48, callback);
    };
}

co(function* () {
    console.log((yield spawnTokenBuf()).toString('base64'));
});
于 2015-05-28T05:19:35.287 に答える
0

random-token libを使用できます。とても使いやすいです。:)

var randomToken = require('random-token').create('abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
var token = randomToken(16);

また、異なる塩を使用することはできません

var randomToken = require('random-token');
var token = randomToken(16); // output -> d8d4kd29c40f021 ```
于 2021-11-07T17:15:50.347 に答える