MongoDB C驱动示例程序执行成功但退出时抛出endSessions未授权警告的问题咨询
我正在学习MongoDB C驱动的教程,运行了一个测试连接的示例程序(用来ping数据库),代码如下:
#include <mongoc/mongoc.h> int main(void) { mongoc_client_t *client = NULL; bson_error_t error = {0}; mongoc_server_api_t *api = NULL; mongoc_database_t *database = NULL; bson_t *command = NULL; bson_t reply = BSON_INITIALIZER; int rc = 0; bool ok = true; // Initialize the MongoDB C Driver. mongoc_init(); client = mongoc_client_new("<connection string>"); if (!client) { fprintf(stderr, "Failed to create a MongoDB client.\n"); rc = 1; goto cleanup; } // Set the version of the Stable API on the client. api = mongoc_server_api_new(MONGOC_SERVER_API_V1); if (!api) { fprintf(stderr, "Failed to create a MongoDB server API.\n"); rc = 1; goto cleanup; } ok = mongoc_client_set_server_api(client, api, &error); if (!ok) { fprintf(stderr, "error: %s\n", error.message); rc = 1; goto cleanup; } // Get a handle on the "admin" database. database = mongoc_client_get_database(client, "sample_restaurants"); // does not matter what database I use if (!database) { fprintf(stderr, "Failed to get a MongoDB database handle.\n"); rc = 1; goto cleanup; } // Ping the database. command = BCON_NEW("ping", BCON_INT32(1)); ok = mongoc_database_command_simple( database, command, NULL, &reply, &error ); if (!ok) { fprintf(stderr, "error: %s\n", error.message); rc = 1; goto cleanup; } bson_destroy(&reply); printf("Pinged your deployment. You successfully connected to MongoDB!\n"); // Perform cleanup. cleanup: bson_destroy(command); mongoc_database_destroy(database); mongoc_server_api_destroy(api); mongoc_client_destroy(client); mongoc_cleanup(); return rc; }
程序运行后能成功输出Pinged your deployment. You successfully connected to MongoDB!,但退出时会弹出警告:
2025/07/08 02:21:14.0310: [ 4981]: WARNING: client: Couldn't send "endSessions": (Unauthorized) not authorized on admin to execute command { endSessions: [[{id {4 [28 203 190 94 175 45 73 123 170 86 143 92 173 213 219 217]}}]], $db: "admin", $clusterTime: { clusterTime: {1751955674 24}, signature: { hash: {0 [63 11 33 56 229 121 251 43 192 100 254 6 0 186 230 195 215 177 133 49]}, keyId: 7461260273723113472.000000 } }, apiVersion: "1" }
明明核心功能正常,为什么退出时会出现这个权限警告?
问题原因分析
你的程序能成功ping通数据库,说明核心连接、认证逻辑是正常的。这个警告出现在程序退出的资源清理阶段:MongoDB C驱动在销毁mongoc_client_t对象时,会自动发送endSessions命令来关闭当前会话,但这个命令默认被发送到了admin数据库(从警告日志里的$db: "admin"可以确认)。
而你的连接账号大概率没有被授予admin数据库的endSessions权限,或者你在连接字符串中没有指定正确的认证源(authSource)——如果你的账号是在sample_restaurants(或其他非admin库)下创建的,驱动默认会去admin库查找该账号,自然会触发权限不足的警告。
解决方法
方法1:修改连接字符串指定认证源(推荐)
在你的连接字符串末尾添加authSource参数,指定你账号所在的数据库(比如你代码里用的sample_restaurants),示例:
mongodb://<username>:<password>@your-host:port/?authSource=sample_restaurants
这样驱动在执行认证和后续的endSessions命令时,都会使用你指定的数据库,而不是默认的admin库,就能彻底解决权限问题。
方法2:为账号授予admin库的endSessions权限(不推荐)
如果你确实需要保留默认的admin库作为认证源,可以给你的账号授予admin库的endSessions权限。在MongoDB Shell中执行以下命令:
use admin // 授予最小必要权限:仅允许endSessions命令 db.grantPrivilegesToUser("<your-username>", [ { resource: { db: "admin", collection: "" }, actions: ["endSessions"] } ])
不过这种方法会让普通业务账号获得admin库的权限,不符合最小权限原则,因此更推荐方法1。
补充说明
这个警告不会影响程序的核心功能(比如数据库连接、数据读写),但会产生冗余的日志信息。如果你的应用对日志整洁度有要求,建议尽快修正。
内容来源于stack exchange

