database.setAuthorizer(callback)
callback<Function> | <null> 用于设置授权者的函数,或使用null来清除当前授权者。
设置一个授权回调,当 SQLite 尝试通过预处理语句访问数据或修改数据库模式时将调用该回调。可以用它来实现安全策略、审核访问或限制某些操作。此方法是 sqlite3_set_authorizer() 的封装。
🌐 Sets an authorizer callback that SQLite will invoke whenever it attempts to
access data or modify the database schema through prepared statements.
This can be used to implement security policies, audit access, or restrict certain operations.
This method is a wrapper around sqlite3_set_authorizer().
调用时,回调函数会接收五个参数:
🌐 When invoked, the callback receives five arguments:
actionCode<number> 正在执行的操作类型(例如,SQLITE_INSERT、SQLITE_UPDATE、SQLITE_SELECT)。arg1<string> | <null> 第一个参数(依赖上下文,通常是表名)。arg2<string> | <null> 第二个参数(依赖上下文,通常是列名)。dbName<string> | <null> 数据库的名称。triggerOrView<string> | <null> 导致访问的触发器或视图的名称。
回调函数必须返回以下常量之一:
🌐 The callback must return one of the following constants:
SQLITE_OK- 允许操作。SQLITE_DENY- 拒绝操作(会导致错误)。SQLITE_IGNORE- 忽略此操作(静默跳过)。
SQLite 要求授权回调不能修改调用它的数据库连接,这包括准备和执行语句。当回调在栈上时,任何会这么做的方法都会抛出代码为 ERR_INVALID_STATE 的错误,包括 database.prepare()、database.exec()、该连接语句的执行方法、迭代器和标签存储,以及 database.setAuthorizer() 本身。其他连接仍然可以使用。
🌐 SQLite requires that the authorizer callback not modify the database connection
that invoked it, which includes preparing and stepping statements. Methods that
would do so throw an error with code ERR_INVALID_STATE while the callback is
on the stack, including database.prepare(), database.exec(), the execution
methods of that connection's statements, iterators, and tag stores, and
database.setAuthorizer() itself. Other connections remain usable.
回调也可以在 statement.run()、statement.get() 和类似方法内部调用,因为 SQLite 在执行过程中可能会在模式更改后重新准备语句。
🌐 The callback can also be invoked from within statement.run(),
statement.get(), and similar methods, because SQLite may re-prepare a
statement during execution after a schema change.
另外,目前正在执行的语句不能被重新进入。调用 statement.close() 会释放正在运行的虚拟机,而通过 statement.run()、statement.get()、statement.all()、statement.iterate()、iterator.next()、iterator.return() 或等效的标签存储方法重新运行它,会在执行中重置该虚拟机。所有这些操作都会抛出 ERR_INVALID_STATE 错误。这适用于 SQLite 在执行过程中调用的任何回调,比如用户自定义函数。连接上的其他语句仍然可以使用。
🌐 Separately, a statement that is currently being executed cannot be reentered.
Calling statement.close() on it would free the virtual machine that is
running, and re-running it through statement.run(), statement.get(),
statement.all(), statement.iterate(), iterator.next(),
iterator.return(), or the equivalent tag store methods would reset that
virtual machine mid-execution. All of these throw an ERR_INVALID_STATE error
instead. This applies to any callback SQLite invokes during execution, such as a
user-defined function. Other statements on the connection remain usable.
不涉及任何 SQLite 状态的操作仍可从回调中使用:sqlTagStore.clear(),它只会清除缓存的语句;以及在已耗尽的迭代器上使用的 next() 和 return(),它们会继续返回 { done: true }。
🌐 Operations that touch no SQLite state stay available from the callback:
sqlTagStore.clear(), which only drops cached statements, and next() and
return() on an already-drained iterator, which keep returning
{ done: true }.
const { Database, constants } = require('node:sqlite');
const db = new Database(':memory:');
// Set up an authorizer that denies all table creation
db.setAuthorizer((actionCode) => {
if (actionCode === constants.SQLITE_CREATE_TABLE) {
return constants.SQLITE_DENY;
}
return constants.SQLITE_OK;
});
// This will work
using query = db.prepare('SELECT 1');
query.get();
// This will throw an error due to authorization denial
try {
db.exec('CREATE TABLE blocked (id INTEGER)');
} catch (err) {
console.log('Operation blocked:', err.message);
}import { Database, constants } from 'node:sqlite';
const db = new Database(':memory:');
// Set up an authorizer that denies all table creation
db.setAuthorizer((actionCode) => {
if (actionCode === constants.SQLITE_CREATE_TABLE) {
return constants.SQLITE_DENY;
}
return constants.SQLITE_OK;
});
// This will work
using query = db.prepare('SELECT 1');
query.get();
// This will throw an error due to authorization denial
try {
db.exec('CREATE TABLE blocked (id INTEGER)');
} catch (err) {
console.log('Operation blocked:', err.message);
}