在节点.js中保护随机令牌
Secure random token in Node.js
在这个问题上,Erik需要在Node.js中生成一个安全的随机令牌。有一个方法crypto.randomBytes
生成一个随机缓冲区。但是,node中的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');
});
"十六进制"编码适用于节点 v0.6.x 或更高版本。
如果您不是像我这样的 JS 专家,则为同步选项。不得不花一些时间在如何访问内联函数变量上
var token = crypto.randomBytes(64).toString('hex');
1. 使用纳米第三方库 [新!
<小时 />一个微小的,安全的,URL友好的,唯一的JavaScript字符串ID生成器
https://github.com/ai/nanoid
import { nanoid } from "nanoid";
const id = nanoid(48);
2. 使用 URL 和文件名安全字母进行 Base 64 编码
<小时 />RCF 4648 的第 7 页介绍了如何使用 URL 安全在 base 64 中进行编码。
Node.js>=v14.18.0 原生支持此功能:
const crypto = require("crypto");
/** Sync */
function randomStringAsBase64Url(size) {
return crypto.randomBytes(size).toString("base64url");
}
使用示例:
randomStringAsBase64Url(20);
// Returns "AXSGpLVjne_f7w5Xg-fWdoBwbfs" which is 27 characters length.
请注意,返回的字符串长度将与 size 参数不匹配(size != 最终长度(。
如果您使用的是 Node.js
const crypto = require("crypto");
const base64url = require("base64url");
/** Sync */
function randomStringAsBase64Url(size) {
return base64url(crypto.randomBytes(size));
}
3. 来自有限字符集的加密随机值
<小时 />请注意,使用此解决方案,生成的随机字符串不是均匀分布的。
您还可以从一组有限的字符中构建一个强大的随机字符串,如下所示:
const 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.
使用 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);
}
这在节点 7 中开箱即用,无需任何 Babel 转换
从 Node.js 14.18 和 15.7 开始,内置了 url-safe base64 编码支持:
const token = crypto.randomBytes(48).toString('base64url');
如果你想使用异步版本(因为函数可能必须等待熵(,它可以被承诺以更好地与现代模式保持一致:
const randomBytesAsync = util.promisify(crypto.randomBytes);
const token = (await randomBytesAsync(48)).toString('base64url');
随机 URL 和文件名字符串安全(1 行(
Crypto.randomBytes(48).toString('base64').replace(/'+/g, '-').replace(/'//g, '_').replace(/'=/g, '');
with async/await and promisization。
const crypto = require('crypto')
const randomBytes = Util.promisify(crypto.randomBytes)
const plain = (await randomBytes(24)).toString('base64').replace(/'W/g, '')
生成类似于VjocVHdFiz5vGHnlnwqJKN0NdeHcz8eM
的内容
退房:
var crypto = require('crypto');
crypto.randomBytes(Math.ceil(length/2)).toString('hex').slice(0,length);
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'
如果您想获得promise
,cryptoRandomString.async(options)
添加.async
。
看看real_ates
ES2016的方式,它更正确。
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'));
});
终端中只需写
node -e "console.log(crypto.randomBytes(48).toString('hex'))"
或者在代码中使用:
const randomToken = () => {
crypto.randomBytes(48).toString('hex');
}
https://www.npmjs.com/package/crypto-extra 有一个方法:)
var value = crypto.random(/* desired length */)
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()
来生成随机。
简单的函数,为您提供URL安全且具有base64编码的令牌!这是上面 2 个答案的组合。
const randomToken = () => {
crypto.randomBytes(64).toString('base64').replace(/'//g,'_').replace(/'+/g,'-');
}
0 无依赖的解决方案...适用于浏览器,deno和nodejs(使用新的全球网络加密(
const random = size => btoa(
String.fromCharCode(
...crypto.getRandomValues(
new Uint8Array(size)
)
)
).replaceAll('+', 'x').replaceAll('/', 'I').slice(0, size)
for (let i = 5; i--;) console.log(random(16))
所有 doe 我只会使用一个 uint8array ''w 预定义的长度,并在我需要 uniq 时调用crypto.getRandomValues
(如果有必要,可以切片(,并且从不处理字符串或 base64,base64 只是不必要的开销。(为快速分配大量缓冲区可能代价高昂(
const buf256 = new Uint8Array(256)
const random = crypto.getRandomValues.bind(crypto, buf256)
for (let i = 5; i--;) random()//.slice()
您可以使用random-token
库。 它非常易于使用。 :)
var randomToken = require('random-token').create('abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
var token = randomToken(16);
而且您也不能使用不同的盐
var randomToken = require('random-token');
var token = randomToken(16); // output -> d8d4kd29c40f021 ```
- 使用Javascript获取Twitter访问令牌
- FB.login访问令牌facebook javascript SDK
- React JS:未捕获(在承诺中)语法错误:在位置 0 的 JSON 中意外<令牌
- Phonegap:获取访问令牌时出现LinkedIn登录错误
- 将HTML(支持文件)中的令牌(字符串、数字等)传递给LogiXML
- 未捕获的语法错误:意外的令牌,
- 访问令牌和响应数据
- jQuery$.getJSON抛出意外令牌
- 访问令牌facebook未激活
- 如何使用Google撤销Oauth令牌'的Javascript API
- 当其他解析器认为意外的令牌有效时,json.parse会失败
- OAuth和访问令牌
- javascript api,用于在第三方域上存储身份验证令牌
- 意外的令牌模块生成失败:SyntaxError
- 为什么我在下面的..of循环中得到意外令牌
- 如何安全地获取&使用Facebook应用程序访问令牌发送通知使用PHP&Javascript
- 函数返回错误'令牌{'
- 如何使用随机令牌重新加载带有 AJAX 的 PHP 脚本,URL 正在缓存
- 在节点.js中保护随机令牌
- 根据用户详细信息在Javascript中创建一个随机令牌