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

pouchdb-authentication无法配合.sync时,如何实现PouchDB与CouchDB同步?

问题:PouchDB登录远程CouchDB后同步时出现401未授权错误

我能通过pouch-authentication插件在Node实例中登录远程CouchDB,但调用.sync方法进行复制时,不会使用登录凭据,一直收到401未授权/未认证凭据错误。pouch-authentication文档只提到:

"But the pouchdb-authentication API will operate on your remote PouchDB object, not your local one."

请问该怎么实现实时同步?

我的代码如下:

const PouchDB = require("pouchdb");
const PouchDBAuth = require('pouchdb-authentication');

PouchDB.plugin(PouchDBAuth)

// 创建本地数据库实例
const localDB = new PouchDB('database')

const remoteDB = await new PouchDB("http://127.0.0.1/database", {skip_setup: true})
remoteDB.logIn('user', '12345678', function (err, response) {
    if (err) {
        if (err.name === 'unauthorized' || err.name === 'forbidden') {
          console.log("4", err)
        } else {
           console.log("other")
        }
    }
    remoteDB.getSession(function (err, response) {
        if (err) {
          // 网络错误
        } else if (!response.userCtx.name) {
          // 当前无登录用户
        } else {
          // response.userCtx.name 为当前登录用户
        }
    localDB.sync(remoteDB, {
        live: true
    }).on('change', function (change) {
        // 数据发生变更!
        console.log("Yo, something changed")
    }).on('error', function (err) {
        console.log("Yo, we got an error", err)
        // 同步出错!(可能是用户离线?)
    });
  })
})

解决方案

核心问题是:localDB.sync(remoteDB)执行时,同步过程没有自动携带远程DB的认证会话信息。虽然你已经在remoteDB实例上完成了登录,但PouchDB的sync默认不会传递这些凭据,需要显式配置。

方法1:利用会话Cookie配置同步请求头

登录成功后,从getSession的响应中提取会话Cookie,然后在sync的ajax选项里设置请求头,让同步请求携带认证信息:

修改代码如下:

const PouchDB = require("pouchdb");
const PouchDBAuth = require('pouchdb-authentication');

PouchDB.plugin(PouchDBAuth)

const localDB = new PouchDB('database')

const remoteDB = await new PouchDB("http://127.0.0.1/database", {skip_setup: true})
remoteDB.logIn('user', '12345678', function (err, response) {
    if (err) {
        if (err.name === 'unauthorized' || err.name === 'forbidden') {
          console.log("登录失败:权限不足", err)
        } else {
           console.log("登录失败:其他错误", err)
        }
        return;
    }
    
    remoteDB.getSession(function (err, sessionResponse) {
        if (err) {
          console.log("获取会话失败:网络错误", err)
          return;
        } 
        if (!sessionResponse.userCtx.name) {
          console.log("当前无登录用户")
          return;
        }

        // 提取会话Cookie,用于同步请求的认证
        const sessionCookie = sessionResponse.cookie;
        
        localDB.sync(remoteDB, {
            live: true,
            ajax: {
                headers: {
                    'Cookie': sessionCookie
                }
            }
        }).on('change', function (change) {
            console.log("数据发生变更", change)
        }).on('error', function (err) {
            console.log("同步出错", err)
        });
    })
})

方法2:给远程DB实例设置默认认证头

登录成功后,直接将认证信息(比如Basic Auth头)附加到remoteDB的默认AJAX配置中,这样后续所有操作(包括sync)都会自动携带认证凭据:

const PouchDB = require("pouchdb");
const PouchDBAuth = require('pouchdb-authentication');

PouchDB.plugin(PouchDBAuth)

const localDB = new PouchDB('database')

const remoteDB = await new PouchDB("http://127.0.0.1/database", {skip_setup: true})
remoteDB.logIn('user', '12345678', function (err, response) {
    if (err) {
        if (err.name === 'unauthorized' || err.name === 'forbidden') {
          console.log("登录失败:权限不足", err)
        } else {
           console.log("登录失败:其他错误", err)
        }
        return;
    }

    // 构造Basic Auth头(也可以从登录响应中获取Bearer token,根据CouchDB配置调整)
    const basicAuth = 'Basic ' + Buffer.from('user:12345678').toString('base64');
    // 设置远程DB的默认AJAX请求头
    remoteDB.setDefaultAJAXOptions({
        headers: {
            'Authorization': basicAuth
        }
    });

    remoteDB.getSession(function (err, sessionResponse) {
        if (err) {
          console.log("获取会话失败:网络错误", err)
          return;
        } 
        if (!sessionResponse.userCtx.name) {
          console.log("当前无登录用户")
          return;
        }

        localDB.sync(remoteDB, {
            live: true
        }).on('change', function (change) {
            console.log("数据发生变更", change)
        }).on('error', function (err) {
            console.log("同步出错", err)
        });
    })
})

注意事项

  • 会话Cookie存在过期时间,生产环境需要处理Cookie过期后的重新登录逻辑
  • 如果使用Basic Auth,务必在生产环境使用HTTPS协议,避免明文传输用户名和密码
  • Node环境下无需担心跨域问题,若在浏览器环境使用,需确保CouchDB配置允许跨域请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:47:21