int sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData );
此例程将授权回调注册到第一个参数提供的特定 数据库连接。 当 sqlite3_prepare() 或其变体 sqlite3_prepare_v2()、sqlite3_prepare_v3()、sqlite3_prepare16()、sqlite3_prepare16_v2() 和 sqlite3_prepare16_v3() 编译 SQL 语句时,会调用授权回调。 在编译过程中的各个点,当创建逻辑以执行各种操作时,会调用授权回调以查看是否允许这些操作。 授权回调应返回 SQLITE_OK 以允许操作,SQLITE_IGNORE 以禁止特定操作但允许 SQL 语句继续编译,或 SQLITE_DENY 以导致整个 SQL 语句被拒绝并出现错误。 如果授权回调返回的值不是 SQLITE_IGNORE、SQLITE_OK 或 SQLITE_DENY,则触发授权回调的 sqlite3_prepare_v2() 或等效调用将失败并出现错误消息。
当回调返回 SQLITE_OK 时,表示请求的操作已成功。 当回调返回 SQLITE_DENY 时,触发授权回调的 sqlite3_prepare_v2() 或等效调用将失败,并出现错误消息,说明访问被拒绝。
授权回调的第一个参数是 sqlite3_set_authorizer() 接口的第三个参数的副本。 回调的第二个参数是一个整数 操作代码,它指定要授权的特定操作。 回调的第三到第六个参数要么是 NULL 指针,要么是包含有关要授权的操作的更多详细信息的以零结尾的字符串。 应用程序必须始终准备好遇到授权回调的第三到第六个参数中的任何 NULL 指针。
如果操作代码为 SQLITE_READ 且回调返回 SQLITE_IGNORE,则将构建 准备好的语句 语句,以将 NULL 值替换为将被读取的表列(如果返回 SQLITE_OK)。 SQLITE_IGNORE 返回值可用于拒绝不受信任的用户访问表的单个列。 当表被 SELECT 引用但没有从该表中提取任何列值时(例如在类似“SELECT count(*) FROM tab”的查询中),则 SQLITE_READ 授权回调将为该表调用一次,其列名为空字符串。 如果操作代码为 SQLITE_DELETE 且回调返回 SQLITE_IGNORE,则 DELETE 操作将继续,但将禁用 截断优化,并且所有行都将被逐个删除。
当从不受信任的来源 准备 SQL 语句时,将使用授权程序来确保 SQL 语句不会尝试访问它们无权查看的数据,或不会尝试执行破坏数据库的恶意语句。 例如,应用程序可能允许用户输入任意 SQL 查询以供数据库评估。 但是,应用程序不希望用户能够随意更改数据库。 然后可以在 准备 用户输入的 SQL 时实施授权程序,以禁止除 SELECT 语句以外的所有操作。
需要处理来自不受信任来源的 SQL 的应用程序也可以考虑使用 sqlite3_limit() 降低资源限制,并使用 max_page_count PRAGMA 限制数据库大小,此外还可以使用授权程序。
一次只能在一个数据库连接上设置一个授权程序。 每次调用 sqlite3_set_authorizer() 都会覆盖之前的调用。 通过安装 NULL 回调来禁用授权程序。 默认情况下禁用授权程序。
授权回调不得执行任何会修改调用授权回调的数据库连接的操作。 请注意,sqlite3_prepare_v2() 和 sqlite3_step() 都修改了它们的数据库连接,以便在本段中了解“修改”的含义。
当使用 sqlite3_prepare_v2() 准备语句时,由于模式更改,语句可能会在 sqlite3_step() 期间重新准备。 因此,应用程序应确保在 sqlite3_step() 期间,正确的授权回调仍然存在。
请注意,授权回调仅在 sqlite3_prepare() 或其变体期间被调用。 在 sqlite3_step() 中的语句评估期间不会执行授权,除非如上一段所述,sqlite3_step() 在模式更改后调用 sqlite3_prepare_v2() 来重新准备语句。