javascript - example - Asegurar el token aleatorio en Node.js
pbkdf2 node (11)
0. Usando la biblioteca de terceros de nanoid [¡NUEVO!]
Un generador de ID de cadena único, pequeño y seguro para URL
const nanoid = require("nanoid");
const id = nanoid(48);
1. Base 64 Codificación con URL y alfabeto de nombre de archivo seguro
La página 7 de RCF 4648 describe cómo codificar en base 64 con seguridad de URL. Puede usar una biblioteca existente como base64url para hacer el trabajo.
La función será:
var crypto = require(''crypto'');
var base64url = require(''base64url'');
/** Sync */
function randomStringAsBase64Url(size) {
return base64url(crypto.randomBytes(size));
}
Ejemplo de uso:
randomStringAsBase64Url(20);
// Returns ''AXSGpLVjne_f7w5Xg-fWdoBwbfs'' which is 27 characters length.
Tenga en cuenta que la longitud de la cadena devuelta no coincidirá con el argumento de tamaño (tamaño! = Longitud final).
2. Crypto valores aleatorios de un conjunto limitado de caracteres
Tenga en cuenta que con esta solución la cadena aleatoria generada no se distribuye uniformemente.
También puedes construir una cadena aleatoria fuerte a partir de un conjunto limitado de caracteres como ese:
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'');
}
Ejemplo de uso:
randomAsciiString(20);
// Returns ''rmRptK5niTSey7NlDk5y'' which is 20 characters length.
randomString(20, ''ABCDEFG'');
// Returns ''CCBAAGDGBBEGBDBECDCE'' which is 20 characters length.
En esta pregunta, Erik necesita generar un token aleatorio seguro en Node.js. Existe el método crypto.randomBytes
que genera un Buffer aleatorio. Sin embargo, la codificación base64 en el nodo no es segura para la URL, incluye /
y +
lugar de -
y _
. Por lo tanto, la forma más fácil de generar dicho token que he encontrado es
require(''crypto'').randomBytes(48, function(ex, buf) {
token = buf.toString(''base64'').replace(////g,''_'').replace(//+/g,''-'');
});
¿Hay una forma más elegante?
Aquí hay una versión asíncrona tomada textualmente de la respuesta anterior de @Yves M.
var crypto = require(''crypto'');
function createCryptoString(length, chars) { // returns a promise which renders a crypto string
if (!chars) { // provide default dictionary of chars if not supplied
chars = ''abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'';
}
return new Promise(function(resolve, reject) {
var charsLength = chars.length;
if (charsLength > 256) {
reject(''parm chars length greater than 256 characters'' +
'' masks desired key unpredictability'');
}
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];
}
resolve(result.join(''''));
});
}
// --- now generate crypto string async using promise --- /
var wantStringThisLength = 64; // will generate 64 chars of crypto secure string
createCryptoString(wantStringThisLength)
.then(function(newCryptoString) {
console.log(newCryptoString); // answer here
}).catch(function(err) {
console.error(err);
});
Con asíncrono / espera y promisification .
const crypto = require(''crypto'')
const randomBytes = Util.promisify(crypto.randomBytes)
const plain = (await randomBytes(24)).toString(''base64'').replace(//W/g, '''')
Genera algo similar a VjocVHdFiz5vGHnlnwqJKN0NdeHcz8eM
El módulo anyid proporciona una API flexible para generar varios tipos de ID / código de cadena.
Para generar una cadena aleatoria en A-Za-z0-9 utilizando 48 bytes aleatorios:
const id = anyid().encode(''Aa0'').bits(48 * 8).random().id();
// G4NtiI9OYbSgVl3EAkkoxHKyxBAWzcTI7aH13yIUNggIaNqPQoSS7SpcalIqX0qGZ
Para generar una cadena de alfabeto de longitud fija rellenada por bytes aleatorios:
const id = anyid().encode(''Aa'').length(20).random().id();
// qgQBBtDwGMuFHXeoVLpt
Internamente usa crypto.randomBytes()
para generar al azar.
La forma correcta y actualizada de hacer esto de forma asincrónica utilizando los estándares de asíncrono de ES 2016 y esperar (a partir del Nodo 7) sería la siguiente:
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);
}
Esto funciona fuera de la caja en el Nodo 7 sin ninguna transformación de Babel
Mira real_ates
ES2016 camino, es más correcto.
Modo ECMAScript 2016 (ES7)
import crypto from ''crypto'';
function spawnTokenBuf() {
return function(callback) {
crypto.randomBytes(48, callback);
};
}
async function() {
console.log((await spawnTokenBuf()).toString(''base64''));
};
Generador / Yield Way
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''));
});
Opción sincrónica en caso de que no seas un experto en JS como yo. Tuvo que dedicar algo de tiempo a cómo acceder a la variable de función en línea
var token = crypto.randomBytes(64).toString(''hex'');
Prueba crypto.randomBytes() :
require(''crypto'').randomBytes(48, function(err, buffer) {
var token = buffer.toString(''hex'');
});
La codificación ''hex'' funciona en el nodo v0.6.xo más reciente.
Revisa:
var crypto = require(''crypto'');
crypto.randomBytes(Math.ceil(length/2)).toString(''hex'').slice(0,length);
URL aleatoria y cadena de nombre de archivo segura (1 trazador de líneas)
Crypto.randomBytes(48).toString(''base64'').replace(//+/g, ''-'').replace(////g, ''_'').replace(//=/g, '''');
https://www.npmjs.com/package/crypto-extra tiene un método para ello :)
var value = crypto.random(/* desired length */)