在this question中,Erik需要在Node.js中生成安全随机令牌。方法crypto.randomBytes
生成随机缓冲区。但是,节点中的base64编码不是url-safe,它包括/
和+
,而不是-
和_
。因此,我发现生成此类令牌的最简单方法是
require('crypto').randomBytes(48, function(ex, buf) {
token = buf.toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
});
有更优雅的方式吗?
答案 0 :(得分:311)
require('crypto').randomBytes(48, function(err, buffer) {
var token = buffer.toString('hex');
});
' hex'编码在节点v0.6.x或更新版本中工作。
答案 1 :(得分:196)
同步选项。不得不花一些时间来访问内联函数变量
var token = crypto.randomBytes(64).toString('hex');
答案 2 :(得分:66)
用于JavaScript的小巧,安全,对URL友好,唯一的字符串ID生成器
const nanoid = require("nanoid");
const id = nanoid(48);
Page 7 of RCF 4648描述了如何使用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)不匹配。
请注意,使用此解决方案,生成的随机字符串不是均匀分布的。
您还可以使用以下有限字符集构建强大的随机字符串:
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.
答案 3 :(得分:10)
使用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);
}
这在Node 7中开箱即用,没有任何Babel转换
答案 4 :(得分:7)
随机URL和文件名字符串安全(1个班轮)
Crypto.randomBytes(48).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
答案 5 :(得分:6)
使用async / await和promisification。
E
生成与const crypto = require('crypto')
const randomBytes = Util.promisify(crypto.randomBytes)
const plain = (await randomBytes(24)).toString('base64').replace(/\W/g, '')
答案 6 :(得分:5)
看看real_ates
ES2016的方式,它更正确。
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'));
});
答案 7 :(得分:4)
退房:
var crypto = require('crypto');
crypto.randomBytes(Math.ceil(length/2)).toString('hex').slice(0,length);
答案 8 :(得分:2)
npm模块anyid提供灵活的API来生成各种字符串ID /代码。
使用48个随机字节在A-Za-z0-9中生成随机字符串:
const id = anyid().encode('Aa0').bits(48 * 8).random().id();
// G4NtiI9OYbSgVl3EAkkoxHKyxBAWzcTI7aH13yIUNggIaNqPQoSS7SpcalIqX0qGZ
生成由随机字节填充的固定长度字母表字符串:
const id = anyid().encode('Aa').length(20).random().id();
// qgQBBtDwGMuFHXeoVLpt
在内部,它使用crypto.randomBytes()
生成随机。
答案 9 :(得分:1)
这是从@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);
});
答案 10 :(得分:1)
https://www.npmjs.com/package/crypto-extra有一个方法:)
var value = crypto.random(/* desired length */)
答案 11 :(得分:1)
一个简单的函数,可为您提供URL安全且具有base64编码的令牌!它是上面两个答案的组合。
const randomToken = () => {
crypto.randomBytes(64).toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
}
答案 12 :(得分:0)
crypto-random-string 是一个很好的模块。
const cryptoRandomString = require('crypto-random-string');
cryptoRandomString({length: 10});
// => '2cf05d94db'
cryptoRandomString({length: 10, type: 'base64'});
// => 'YMiMbaQl6I'
cryptoRandomString({length: 10, type: 'url-safe'});
// => 'YN-tqc8pOw'
cryptoRandomString({length: 10, type: 'numeric'});
// => '8314659141'
cryptoRandomString({length: 6, type: 'distinguishable'});
// => 'CDEHKM'
cryptoRandomString({length: 10, type: 'ascii-printable'});
// => '`#Rt8$IK>B'
cryptoRandomString({length: 10, type: 'alphanumeric'});
// => 'DMuKL8YtE7'
cryptoRandomString({length: 10, characters: 'abc'});
// => 'abaaccabac'
cryptoRandomString.async(options)
如果想获得.async
,请添加promise
。