我正在一个离子应用程序中使用PouchDB和CouchDB。虽然我可以在Chrome和Android上成功同步本地和远程数据库,但在Safari / iOS上运行同步命令时,我会收到未经授权的错误。下面是我的数据库服务提供程序的简化版本。
import PouchDB from 'pouchdb';
import PouchDBAuthentication from 'pouchdb-authentication';
@Injectable()
export class CouchDbServiceProvider {
private db: any;
private remote: any;
constructor() {
PouchDB.plugin(PouchDBAuthentication);
this.db = new PouchDB('localdb', {skip_setup: true});
}
...
login(credentials) {
let couchDBurl = 'URL of my couchDB database';
this.remote = new PouchDB(couchDBurl);
this.remote.logIn(credentials.username, credentials.password, function (err, response) {
if (err) { concole.log('login error') }
else {
let options = { live: true, retry: true, continuous: true };
this.db.sync(this.remote, options).on('error', (err_) => { console.log('sync error')});
}
})
}
...
}
在上面的代码中,this.remote.logIn(...)
成功,但this.db.sync(...)
失败。我已经通过开发者工具的网络选项卡检查了请求,我认为问题是this.remote.logIn(...)
的响应头中返回的cookie没有被后续调用使用(因此出现了未授权错误)。在Safari上启用第三方cookie后,该问题得到了修复,iOS上没有此选项。
如何解决此问题?
我正在考虑的一个可能的解决方案是覆盖fetch
以使用原生http客户端(即,@ionic-native/http
的HTTP
示例)。似乎修改http客户端是可能的(例如,根据此对话),但我不确定如何实现。
3条答案
按热度按时间eyh26e7m1#
更改HTTP管道听起来像是一个非常糟糕的主意-主要是时间成本-除非您绝对必须使用会话/cookie...如果您不这样做,请继续阅读。
正如这里提到的关于pouchDB安全性,我尝试使用pouchdb-authentication时,它是 * 积极维护 *,并采取了另一种路线,由于多个问题(我不记得具体的,这是6年前)。
请注意,最后一次提交pouchdb-authentication似乎是在3年前。
再加上过去几年对插件缺乏热爱,这使得一个新项目需要增加一笔危险的技术债务。
如果可能,只需在创建(或打开)远程数据库时使用
auth
选项发送凭据,例如我不记得为什么,但我编写的代码本质上是如下所示的内容,并重复使用它令人作呕,因为它只与
fetch
选项一起工作我相信我之所以选择这种方法,是因为我的身份验证工作流的性质在本答案的第一个链接中讨论过。
fruv7luv2#
我同意@RamblinRose的观点,即在定义PouchDB对象时可能必须手动包含头。
我自己已经找到了一个解决方案,当与JWT的工作,需要包括在头部的同步目的。
见此答案.注:RxDB在引擎盖下使用了PouchDB,所以它适用于这种情况。它帮助我同步,希望它也能帮助你!
https://stackoverflow.com/a/64503760/5012227
5cg8jx4n3#
我正在考虑的一个可能的解决方案是覆盖fetch以使用原生http客户端(即,来自@ionic-native/http的HTTP示例)。似乎修改http客户端是可能的(例如,根据此对话),但我不确定如何实现。
是的,这是一个可能的选择--特别是如果你想使用SSL pinning,它只适用于原生请求。而且你不需要担心CORS(除了
ionic serve
)。例如,您可以通过使用现有的
fetch
-polyfill并对其进行s.t.修改来实现这一点。它使用http插件而不是xhr。由于您在与CouchDB交互时只处理JSON,因此可以丢弃大部分polyfill。