You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQLite3 C++数据库中正确实现带验证的登录模块

SQLite3登录验证的SQL查询与代码修正

核心问题分析

你的代码存在三个关键问题:

  • SQL语句语法错误:SELECT ... INTO 用于将查询结果写入新表/文件,不是匹配账号密码的正确写法;直接拼接用户输入到SQL语句中还会引发SQL注入风险。
  • 函数调用参数缺失:SignIN 中调用 selectData 时没有传入用户输入的login和password参数。
  • 缺少验证结果判断:当前代码仅输出查询结果,无法判断账号密码是否匹配,无法控制程序流程。

修正后的完整代码

#include <sqlite3.h>
#include <iostream>
#include <string>
#include <cstdlib>

// 验证登录,返回true表示匹配成功,false失败
static bool verifyLogin(const char* dbPath, const std::string& login, const std::string& password) {
    sqlite3* DB;
    sqlite3_stmt* stmt;
    int exit = sqlite3_open(dbPath, &DB);

    if (exit != SQLITE_OK) {
        std::cerr << "无法打开数据库: " << sqlite3_errmsg(DB) << std::endl;
        sqlite3_close(DB);
        return false;
    }

    // 使用参数绑定的SQL语句,避免SQL注入
    const char* sql = "SELECT 1 FROM Users WHERE Login = ? AND Password = ? AND Status = 1;";
    exit = sqlite3_prepare_v2(DB, sql, -1, &stmt, nullptr);

    if (exit != SQLITE_OK) {
        std::cerr << "SQL语句准备失败: " << sqlite3_errmsg(DB) << std::endl;
        sqlite3_close(DB);
        return false;
    }

    // 绑定登录名和密码参数
    sqlite3_bind_text(stmt, 1, login.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, password.c_str(), -1, SQLITE_STATIC);

    // 执行查询,检查是否有匹配记录
    bool loginSuccess = false;
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        loginSuccess = true; // 查到匹配记录,验证成功
    }

    // 清理资源
    sqlite3_finalize(stmt);
    sqlite3_close(DB);
    return loginSuccess;
}

void SignIN(const char* dir) {
    std::string login, password;
    bool isAuthenticated = false;

    while (!isAuthenticated) {
        std::cout << "Login: ";
        std::cin >> login;
        std::cout << "Password: ";
        std::cin >> password;

        isAuthenticated = verifyLogin(dir, login, password);

        if (!isAuthenticated) {
            std::cout << "账号或密码错误,请重新输入!" << std::endl;
        } else {
            std::cout << "登录成功!" << std::endl;
            // 这里继续后续程序逻辑
        }
    }
}

// 示例主函数
int main() {
    SignIN("your_database.db");
    return 0;
}

关键修正说明

  1. 安全的SQL查询方式:
    • 使用sqlite3_prepare_v2和参数绑定(sqlite3_bind_text)替代字符串拼接,彻底避免SQL注入攻击。
    • SQL语句改为查询是否存在匹配记录(SELECT 1),无需返回完整账号密码,提升效率和安全性。
  2. 验证结果返回:verifyLogin函数返回布尔值,直接告知登录是否成功,方便上层逻辑控制。
  3. 循环验证逻辑:SignIN中加入循环,直到用户输入正确的账号密码为止。
  4. 资源管理:确保sqlite3的句柄、语句对象都被正确关闭和释放,避免内存泄漏。

重要安全提醒

绝对不要明文存储用户密码!当前代码为演示逻辑使用了明文比对,实际开发中应该:

  • 注册时对密码进行哈希处理(例如使用bcrypt、Argon2等专业哈希算法)
  • 登录时将用户输入的密码做相同哈希处理,再与数据库中存储的哈希值比对

内容的提问来源于stack exchange,提问作者Axiles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:45:33