[javascript] Node.js의 보안 임의 토큰

에서 이 질문에 에릭은 Node.js.에 안전한 임의 토큰을 생성 할 필요가 crypto.randomBytes무작위 버퍼를 생성하는 방법 이 있습니다. 그러나, 노드에서 base64 인코딩은 URL 안전하지 않다 그것이 포함 /하고 +대신 -하고 _. 따라서 내가 찾은 그러한 토큰을 생성하는 가장 쉬운 방법은

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

더 우아한 방법이 있습니까?



답변

crypto.randomBytes () 사용해보십시오 :

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

’16 진수 ‘인코딩은 노드 v0.6.x 이상에서 작동합니다.


답변

나와 같은 JS 전문가가 아닌 경우 동기 옵션. 인라인 함수 변수에 액세스하는 방법에 시간을 보냈습니다

var token = crypto.randomBytes(64).toString('hex');


답변

0. nanoid 타사 라이브러리 사용 [NEW!]

JavaScript를위한 작고 안전하며 URL 친화적 인 고유 한 문자열 ID 생성기

https://github.com/ai/nanoid

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

1. 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! = final length)와 일치하지 않습니다.

2. 제한된 문자 집합에서 암호화 된 임의의 값

이 솔루션을 사용하면 생성 된 임의 문자열이 균일하게 분산되지 않습니다.

다음과 같은 제한된 문자 세트에서 강력한 임의 문자열을 작성할 수도 있습니다.

var crypto = require('crypto');

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

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

  var randomBytes = crypto.randomBytes(length);
  var result = new Array(length);

  var cursor = 0;
  for (var 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.


답변

ES 2016 표준 async and await (노드 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);
}

이것은 바벨 변환없이 노드 7에서 즉시 작동합니다.


답변

임의 URL 및 파일 이름 문자열 안전 (1 라이너)

Crypto.randomBytes(48).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');


답변

체크 아웃 :

var crypto = require('crypto');
crypto.randomBytes(Math.ceil(length/2)).toString('hex').slice(0,length);


답변

비동기 / 대기 및 약속 .

const crypto = require('crypto')
const randomBytes = Util.promisify(crypto.randomBytes)
const plain = (await randomBytes(24)).toString('base64').replace(/\W/g, '')

비슷한 것을 생성합니다 VjocVHdFiz5vGHnlnwqJKN0NdeHcz8eM