各位 Java 大佬好,先给大佬倒茶。关于 jdbc 与 mysql 交互问题

2021-11-04 17:20:14 +08:00
 Lyv5

是这样我想知道 jdbc 与 mysql 交互,源码上网边看边查到 mysqlIO.class ,问题是我如果 jdbc 里面数据库名或者密码错了(虽然我知道错的),底层是怎么判断的 ,目的是要这套判断,和判断结果,套用在自己的数据上面,相当于借用他们的标准套在我们的数据库上面,以后也好形成统一。 还望各位大佬们不吝赐教,指条明路。我是菜鸡,只管喷。 祝大佬 情绪稳定,睡眠良好,头发浓密

目前代码看到这里 mysqlIO.class

void secureAuth411(Buffer packet, int packLength, String user, String password, String database, boolean writeClientParams) throws SQLException { String enc = this.getEncodingForHandshake(); if (packet == null) { packet = new Buffer(packLength); }

if (writeClientParams) {
    if (this.use41Extensions) {
        if (this.versionMeetsMinimum(4, 1, 1)) {
            packet.writeLong(this.clientParam);
            packet.writeLong((long)this.maxThreeBytes);
            this.appendCharsetByteForHandshake(packet, enc);
            packet.writeBytesNoNull(new byte[23]);
        } else {
            packet.writeLong(this.clientParam);
            packet.writeLong((long)this.maxThreeBytes);
        }
    } else {
        packet.writeInt((int)this.clientParam);
        packet.writeLongInt(this.maxThreeBytes);
    }
}
// 设置用户名
packet.writeString(user, enc, this.connection);
if (password.length() != 0) {
    packet.writeByte((byte)20);

    
    try {
        // 设置密码 
        packet.writeBytesNoNull(Security.scramble411(password, this.seed, this.connection.getPasswordCharacterEncoding()));
    } catch (NoSuchAlgorithmException var11) {
        throw SQLError.createSQLException(Messages.getString("MysqlIO.95") + Messages.getString("MysqlIO.96"), "S1000", this.getExceptionInterceptor());
    } catch (UnsupportedEncodingException var12) {
        throw SQLError.createSQLException(Messages.getString("MysqlIO.95") + Messages.getString("MysqlIO.96"), "S1000", this.getExceptionInterceptor());
    }
} else {
    packet.writeByte((byte)0);
}

// 设置数据库名
if (this.useConnectWithDb) {
    packet.writeString(database, enc, this.connection);
} else {
    packet.writeByte((byte)0);
}

if ((this.serverCapabilities & 1048576) != 0) {
    this.sendConnectionAttributes(packet, enc, this.connection);
}
// 向 Mysql 服务器发送登录信息包(用户名、密码、此 Socket 连接默认选择的数据库)
this.send(packet, packet.getPosition());
byte var10002 = this.packetSequence;
this.packetSequence = (byte)(var10002 + 1);
byte savePacketSequence = var10002;

// 读取 Mysql 服务器登录检验后发送的状态信息,如果成功就返回,如果登录失败则抛出异常 
Buffer reply = this.checkErrorPacket();
if (reply.isLastDataPacket()) {
    ++savePacketSequence;
    this.packetSequence = savePacketSequence;
    packet.clear();
    String seed323 = this.seed.substring(0, 8);
    packet.writeString(Util.newCrypt(password, seed323));
    this.send(packet, packet.getPosition());
    this.checkErrorPacket();
}

}

2400 次点击
所在节点    Java
12 条回复
xiangyuecn
2021-11-04 17:48:27 +08:00
你的段位不是菜鸡,是会写数据库驱动的牛逼大佬🐶
AlbertChen
2021-11-04 18:03:04 +08:00
misaka19000
2021-11-04 18:12:43 +08:00
直接 tcpdump 抓包看
zjsxwc
2021-11-04 18:39:55 +08:00
膜拜大佬
Lyv5
2021-11-05 08:39:31 +08:00
@AlbertChen 好的我研究下
Lyv5
2021-11-05 08:39:52 +08:00
@xiangyuecn 大哥我真菜鸡
lei2j
2021-11-05 09:30:44 +08:00
你都搞这个了,那我就是菜鸡中的弱鸡了
yizmaoaa
2021-11-05 09:56:54 +08:00
其实你在驱动里是看不到怎么判断用户名密码是错的,驱动包也只是根据数据库的协议发包的。至于用户名密码是对的还是错的,是你驱动包发数据过去,然后 Mysql Server 里判断然后给客户端返回异常信息的
Lyv5
2021-11-05 10:23:38 +08:00
@yizmaoaa 大哥请留步,我一直看的是 java 端的源码,你的意思是我应该去找 mysql 端做了什么判断是嘛
DsuineGP
2021-11-05 14:14:20 +08:00
@Lyv5 可以看一下 mycat 鉴权这一块的代码,也是用 java 写的,大致的逻辑跟你想实现的很像,拦截 mysql 一端的错误信息并包装一层放回给客户端
vinle
2021-11-05 14:49:52 +08:00
首先膜拜一下,楼主过于谦虚,能为一个新的数据库作贡献是非常强的了。

然后对于 LZ 的问题,

“底层是怎么判断的” :mysql 的 server 与 client 通信已经算是很高层的实现了,至于底层,楼主没说清楚到底多底层,看楼主的代码注释应该是指:Client (使用 jdbc 的客户端程序)识别 Server(数据库服务器)返回的 Packet (响应)的过程中,怎么判断 mysql 的错误类型的。
其实楼主已经分析得非常完整了,因为就是 MysqlIO 类的 checkErrorPacket 来判断的,更完整的调用链是:/ secureAuth411 / -> / checkErrorPacket() / -> / checkErrorPacket(-1) / -> / checkErrorPacket(resultPacket) / -> / 你要的逻辑 /

“不看 mysql 端 就是怎么知道密码错误...” : 关于这个,一般来说这些错误代码的规范,都会有公开的文档,方便 mysql 社区参考,所以不用担心一般不需要深入到 mysql 的源码里边,对于特定版本的规范也应该不一样,我就随便找了个版本索引一下了: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-error-sqlstates.html ,进去后直接搜“PASSWORD”大概率就能找到你想要的了。
Lyv5
2021-11-08 09:08:54 +08:00
@vinle 首先感谢老哥,给老哥倒一杯热咖啡,提出的思路是对的,以及老哥给的 mysql 连接,我也查过去了。得到了想要的,菜鸡提的问题有点模糊还望海涵 ,最后还是谢谢老哥指导。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/813086

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX