In this question Erik needs to generate a secure random token in Node.js. There\'s the method crypto.randomBytes
that generates a random Buffer. However, the ba
The up-to-date right way to do this asynchronously using ES 2016 standards of async and await (as of Node 7) would be the following:
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);
}
This works out of the box in Node 7 without any Babel transformations
The npm module anyid provides flexible API to generate various kinds of string ID / code.
To generate random string in A-Za-z0-9 using 48 random bytes:
const id = anyid().encode('Aa0').bits(48 * 8).random().id();
// G4NtiI9OYbSgVl3EAkkoxHKyxBAWzcTI7aH13yIUNggIaNqPQoSS7SpcalIqX0qGZ
To generate fixed length alphabet only string filled by random bytes:
const id = anyid().encode('Aa').length(20).random().id();
// qgQBBtDwGMuFHXeoVLpt
Internally it uses crypto.randomBytes()
to generate random.
With async/await and promisification.
const crypto = require('crypto')
const randomBytes = Util.promisify(crypto.randomBytes)
const plain = (await randomBytes(24)).toString('base64').replace(/\W/g, '')
Generates something similar to VjocVHdFiz5vGHnlnwqJKN0NdeHcz8eM
Synchronous option in-case if you are not a JS expert like me. Had to spend some time on how to access the inline function variable
var token = crypto.randomBytes(64).toString('hex');
Try crypto.randomBytes():
require('crypto').randomBytes(48, function(err, buffer) {
var token = buffer.toString('hex');
});
The 'hex' encoding works in node v0.6.x or newer.
Random URL and filename string safe (1 liner)
Crypto.randomBytes(48).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');