没有运气找到之前提出的问题;并不完全确定如何表达它。
无论如何,我将从我试图解决的问题开始。 在我们的应用程序中,我们使用npm redis模块将数据缓存到Redis。我们初始化客户端并在我们的业务逻辑中使用它并直接使用它。 但是,现在我们要加密我们缓存的数据。因此,我没有在主要业务逻辑中使用所有加密/解密逻辑,而是认为如果我们可以简单地包装客户端以便所有调用都包括加密/解密步骤,那就更好了。 问题是redis客户端有一大堆导出的函数(set,hset,hmset,setex等等),所以单独覆盖/包装每个函数会很痛苦。
所以,我的问题是,有没有办法包装整个客户端?因此,如果调用任何客户端函数,则调用预处理函数,该函数将事先执行加密/解密,然后调用redis客户端自己的函数。
E.g。
myClient.foo()
call encrypt()
call redisClient.foo()
但是对于redis客户端的每个导出函数都会自动出现上述情况吗?
同样,这是早期思考,所以这样做甚至没有意义。需要确定某些依赖于某些功能的行为;例如它调用加密,解密等。 但是,我想我想知道上述是否有可能以干净的方式进行?即使是一个简单的通用函数,比如记录每个客户调用或者不依赖于函数的东西。
修改 试着简化我想做的事情。 如果我们采用加密方程式。 是否可以拥有动态导出的函数名称? 像下面这样的东西,除了" foo"是动态的,可用于调用同名的redisClient导出函数:
exports.myClient.foo = function(){ //where foo can be any value?
genericFunction(arguments);
redisClient[foo].apply(arguments)
}
答案 0 :(得分:0)
您所要求的当然是可能的,您需要做的只是花一些时间来创建类来包装redis客户端以添加加密。据我所知,使用默认客户端(https://www.npmjs.com/package/redis),没有简单的方法可以在输入从GET操作返回之前将输入存储到redis或输出之前修改输入。 / p>
假设您只在SET和GET操作中使用redis,您可以执行以下操作。
我假设您在特定模块中具有加密逻辑,并且加密算法是同步的:
// encryption.js
"use strict";
function Encryption(key) {
this.key = key;
}
Encryption.prototype.enc(value) {
// Encrypts the value using the key and returns it...
}
Encryption.prototype.dec(value) {
// Decrypts the value using the key and returns it...
}
module.exports = Encryption
我们的redis包装器将如下所示:
// encryptedRedisClient.js
"use strict";
function EncryptedRedisClient(redisClient, encryption)
{
this.redisClient = redisClient;
this.encryption = encryption;
}
EncryptedRedisClient.prototype.get(key, cb)
{
this.client.get(key, function (err, reply) {
if (err) {
cb(err);
}
cb(null, this.encrypt.dec(reply.toString()));
});
}
EncryptedRedisClient.prototype.set(key, value, cb)
{
var encValue = this.encryption.enc(value);
this.client.set(key, encValue, cb);
}
module.exports = EncryptedRedisClient;
最后,您可以像这样使用包装的客户端:
"use strict";
var redis = require('redis');
var client = redis.createClient(); // add the needed options here
var Encryption = require('./encryption');
var EncryptedRedisClient = require('./encryptedRedisClient');
var encClient = new EncryptedRedisClient(client, new Encryption('some_secret_key'));
encClient.set(...);
encClient.get(...);
我还没有对代码进行测试,因此可能存在一些小问题,但这应该是一个很好的起点。