如何轻松包装整个(Redis)客户端

时间:2016-04-14 10:19:54

标签: node.js function redis

没有运气找到之前提出的问题;并不完全确定如何表达它。

无论如何,我将从我试图解决的问题开始。 在我们的应用程序中,我们使用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)
}

1 个答案:

答案 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(...);

我还没有对代码进行测试,因此可能存在一些小问题,但这应该是一个很好的起点。