中间件MySQL 客户端_如何在mysql中间件层实现客户端连…

很多情况下,mysql中间件程序会集成连接池功能,并且客户端的登录用户和实际操作后端数据库的用户为不同的用户。也就是说,中间件程序在客户端登录之前已经使用某个特定的用户名和密码建立了中间件到后端mysql的连接池;客户登入验证通过后就可以直接使用连接池中的连接。

这样设计的好处是可以多个用户共享一个连接池,即避免了每个客户重新创建连接的开销,也避免了为每个客户

准备单独的连接池所带来的浪费。(当然多个用户共享一个连接池还需要有另外的控制机制保证它们的互不干扰。)

而这样设计也带来了客户端连接操作的权限认证问题。因为客户端登录之后使用的是另一个用户名去操作后端数据库,通常这个用户名拥有比客户端登录用户更大的权限,这就导致了权限被放大的问题。

简单的解决办法是为每个登录客户保留它们登录时的认证连接,每次操作之前使用该认证连接查看权限。

这个方法最直接也最简单,但要为每个登录客户端保留一个连接代价有点高,这限制了中间件程序的客户端并发数。并且作为中间件程序,我们可能不需要那么完整的权限控制;很多情况下业务是以库进行区分的,某些场景下只需要确定这个客户端连接是否有权限操作某个库就足够了。

另一个方法是在需要的时候模拟一次客户端登录重新创建一个认证连接。这样做的好处是按需使用连接,避免为每个客户端保留一个认证连接的高昂代价;如果中间件程序登录后的权限认证频率不高,这是非常推荐一种方法。当然它的难点是你没有客户端登录的密码,如何去模拟登录呢?

首先看下mysql客户端是如何登录的,如下是代码示例。代码的输入为客户端密码,服务端返回的随机加密串。

SHA1_CONTEXT sha1_context;

uint8_t hash_stage1[SHA1_HASH_SIZE];

uint8_t hash_stage2[SHA1_HASH_SIZE];

mysql_sha1_reset(&sha1_context);

mysql_sha1_input(&sha1_context, (uint8_t *) password, (unsigned int) strlen(password));

mysql_sha1_result(&sha1_context, hash_stage1);

mysql_sha1_reset(&sha1_context);

mysql_sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE);

mysql_sha1_result(&sha1_context, hash_stage2);

;

mysql_sha1_reset(&sha1_context);

mysql_sha1_input(&sha1_context, (const uint8_t *) message, SCRAMBLE_LENGTH);

mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);

mysql_sha1_result(&sha1_context, (uint8_t *) to);

my_crypt(to, (const unsigned char *) to, hash_stage1, SCRAMBLE_LENGTH);

可以看到首先通过对客户端密码的hash获得 hash_stage1,然后通过对hash_stage1的再hash获得hash_stage2。然后通过将 hash_stage2和服务端随机串的hash结果与hash_stage1进行加密(异或操作)生产最终发给服务端的认证串。

所以,我们只需要能获取到hash_stage1和hash_stage2就可以不用客户端密码直接登录了。

hash_stage2其实就保存在服务端的mysql.user表的password字段中,当然需要进行一下简单的转换,将它转成2进制(参考mysql代码,使用函数hex2octet)。而hash_stage1,参考mysql服务端的认证代码则可以通过hash_stage2,服务端随机认证串以及对应的客户端最终发往服务端的认证串计算出来。

获取到hash_stage2和hash_stage1之后就可以根据新的服务端认证串进行登录了。

如下是示例代码,输入为

1. mysql.user表的password字段,代码中为 dbscale_password

2. 客户端登录时获取的服务端随机认证串,代码中为 message

3. 客户端登录时最终发往服务端的认证串,代码中为 to

4. 这次模拟登录获取的服务端新随机认证串,代码中为 new_message

SHA1_CONTEXT sha1_context;

uint8_t hash_dbscale_s2[SHA1_HASH_SIZE];

// get hash_stage2 using the password in mysql.user

hex2octet(hash_dbscale_s2, dbscale_password, SHA1_HASH_SIZE);

uint8_t hash_dbscale_s1[SHA1_HASH_SIZE];

mysql_sha1_reset(&sha1_context);

mysql_sha1_input(&sha1_context, (const uint8_t *) message, SCRAMBLE_LENGTH);

mysql_sha1_input(&sha1_context, hash_dbscale_s2, SHA1_HASH_SIZE);

mysql_sha1_result(&sha1_context, hash_dbscale_s1);

my_crypt((char *) hash_dbscale_s1, (const unsigned char *)hash_dbscale_s1, (const unsigned char *)to, SCRAMBLE_LENGTH);

上面的代码首先通过mysql.user表的password字段算出hash_stage2,然后通过客户端登录时获取的服务端随机认证串 message 和 客户端登录时最终发往服务端的认证串 to, 计算出hash_stage1.

;

mysql_sha1_reset(&sha1_context);

mysql_sha1_input(&sha1_context, (const uint8_t *) new_message, SCRAMBLE_LENGTH);

mysql_sha1_input(&sha1_context, hash_dbscale_s2, SHA1_HASH_SIZE);

mysql_sha1_result(&sha1_context, (uint8_t *) to);

my_crypt(to, (const unsigned char *) to, (const unsigned char *)hash_dbscale_s1, SCRAMBLE_LENGTH);

上面的代码为通过hash_stage1和hash_stage2,安装新的服务端随机认证串,生产新的最终认证串,进行模拟登录。

转载请注明转自高孝鑫的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以回答这个问题。canal中间件可以实现redis和mysql的数据同步,它可以监控mysql数据库的binlog日志,将数据变更同步到redis中。同时,canal也支持将mysql数据同步到其他数据库,如elasticsearch等。 ### 回答2: Canal中间件是一种用于实现数据库数据同步的工具。它可以实现Redis和MySQL之间的数据同步。 首先,我们需要设置Canal中间件与Redis和MySQL的连接。通过配置Canal中间件的连接参数,使其能够连接到Redis和MySQL数据库。可以设置监控的表和字段,以确定需要同步的数据范围。 当MySQL数据库中的数据发生变化时,Canal中间件会自动捕获这些变化并生成相应的Binlog日志。通过监听MySQL数据库的Binlog日志,Canal中间件能够实时获取更新的数据。 接下来,Canal中间件将获取到的数据进行处理,将变化的数据转换成Redis可以接受的数据格式,并将其写入到Redis数据库中。这样就实现MySQL中数据变化的同步到Redis数据库的功能。 通过Canal中间件,我们可以实现MySQL和Redis之间的双向数据同步。当MySQL中的数据发生改变时,Canal中间件会将变化的数据同步到Redis数据库中。同样地,当Redis中的数据发生改变时,Canal中间件也能够捕获这些变化并同步到MySQL数据库中。 这种数据同步的方式可以提高应用程序的性能和可靠性。通过将热点数据存储到Redis中,可以提高读取性能。同时,由于Canal中间件的实时同步机制,可以保证数据的一致性。 总结起来,Canal中间件可以实现Redis和MySQL之间的数据同步。它通过捕获MySQL数据库的Binlog日志,并将变化的数据转换成Redis可以接受的格式,实现了数据的同步。这种方式可以提高应用程序的性能和可靠性。 ### 回答3: Canal中间件是一个开源的数据同步工具,用于将数据库中的数据同步到其他数据源。在实现Redis和MySQL数据同步的场景下,可以通过以下步骤实现数据的同步: 第一步,安装配置Canal中间件。首先需要在服务器上安装Canal中间件,并配置Canal的相关参数,如数据源的地址、端口号、用户名和密码等。 第二步,配置Canal中间件连接MySQL数据库。需要在Canal配置文件中添加MySQL数据源的相关信息,包括MySQL服务器的地址、端口号、用户名和密码等。 第三步,配置Canal中间件连接Redis数据库。同样需要在Canal配置文件中添加Redis数据源的相关信息,包括Redis服务器的地址、端口号、密码等。 第四步,创建数据库表数据的监听和同步。通过创建Canal的实例,并指定需要监听的数据库和表,可以实现对特定表数据的监听和同步。 第五步,通过Canal中间件MySQL数据同步到Redis。当MySQL数据库中的数据发生变化时,Canal中间件会将变更的数据解析并转发给Redis数据库实现数据的同步。 通过以上步骤,即可实现Redis和MySQL数据的同步。Canal中间件作为数据同步的桥梁,能够实时监听MySQL数据库的变化,并将变更的数据同步到Redis,确保数据的一致性和及时性。 需要注意的是,在配置Canal中间件时,需要确保Canal和MySQL、Redis之间的网络连接正常,并且对应的用户有足够的权限来进行数据操作。同时,还需要进行相关的性能测试和优化,以确保数据同步的效率和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值