javascript - 使用不记名授权将 PouchDB 同步到 Cloudant 时出错
问题描述
我是一位经验丰富的 JavaScript 程序员,但对 PouchDB、Cloudant 和 oAuth 不熟悉。当我尝试使用 Bearer Authorization 同步 PouchDB 和 Cloudant 时,我收到错误消息:
"_reader access is required for this request", status: 401
我正在尝试使用 PouchDB 和 Cloudant 编写一个演示 Web 应用程序。我设置了一个 IBM 帐户。我创建了一项名为 Cloudant-xx 的服务。我选择了身份验证方法:IBM Cloud IAM(我没有选择“and legacy...”)。我去了该服务的仪表板,1) 创建了一个数据库 (myDatabase),2) 选择了屏幕左侧的 head-profile,然后是 [CORS],并禁用了 CORS(用于开发)。
我回到服务,选择了[Service Credentials],并创建了一个新的服务凭证。这给了我一个带有 {"apikey": "ELB4lEVA...IO", ..., "username": "451c...74-bluemix"} 的对象。
我使用 curl 获取访问令牌:
curl -k -X POST \
--header "Content-Type: application/x-www-form-urlencoded" \
--header "Accept: application/json" \
--data-urlencode "grant_type=urn:ibm:params:oauth:grant-type:apikey" \
--data-urlencode "apikey=ELB4lEVA...IO" \
"https://iam.cloud.ibm.com/identity/token"
返回{"access_token":"eyJra...6fJns","token_type":"Bearer","expires_in":3600,"expiration":1558965151,"scope":"ibm openid"}
在一小时内,我将访问令牌复制并粘贴到我的 javascript 代码中,运行代码,并收到错误“此请求需要 _reader 访问权限”(见上文)。我找不到在哪里设置 _reader 访问权限。有谁能够帮我?谢谢!
let localDb;
const localName = "myDatabase";
const remoteUrl = "https://451...d974-bluemix.cloudantnosqldb.appdomain.cloud/myDatabase";
const token = "eyJra...6fJns";
const syncOptions = {
live: true,
retry: true,
continuous: true,
ajax: {
headers: {
Authorization: "Bearer " + token,
},
},
};
localDb = new PouchDB(localName);
localDb.sync(remoteUrl, syncOptions).on('change', function (info) {
console.log(8888, "change", info);
}).on('paused', function (info) {
console.log(8888, "paused", info);
}).on('active', function (info) {
console.log(8888, "active", info);
}).on('denied', function (err) {
console.log(8888, "denied", err);
}).on('complete', function (info) {
console.log(8888, "denied", info);
}).on('error', function (err) {
console.log(8888, "error", err);
});
console.log(4444, localDb);
在控制台中我看到:
4444 PouchDB {__opts: {…}, auto_compaction: undefined, prefix: "_pouch_", name: "myDatabase", _adapter: "idb", …}
index.js:194
451...d974-bluemix.cloudantnosqldb.appdomain.cloud/:1 GET https://451...d974-bluemix.cloudantnosqldb.appdomain.cloud/myDatabase/ 401
index.js:192
8888 "error" CustomPouchError {error: "unauthorized", reason: "_reader access is required for this request", status: 401, name: "unauthorized", message: "_reader access is required for this request", …}
解决方案
我回答了我自己的问题。原来我在关注过时的例子。在 PouchDB 7.0 中,{ajax: {headers: {}} 已替换为 fetch: function (url, opts) {}。另外,我必须使用 PouchDB 实例而不是远程数据库的字符串。
https://pouchdb.com/api.html#create_database
远程数据库的选项:
fetch(url, opts):拦截或覆盖 HTTP 请求,您可以添加或修改与 http 请求相关的任何标头或选项,然后返回新的 fetch Promise。
这现在有效。
let localDb;
const localName = "myDatabase";
const remoteUrl = "https://451...74-bluemix.cloudantnosqldb.appdomain.cloud/myDatabase";
const token = "eyJ...448";
const remoteOptions = {
fetch: function (url, opts) {
opts.headers.set("Authorization", "Bearer " + token);
return PouchDB.fetch(url, opts);
}
};
const syncOptions = {
live: true,
retry: true,
continuous: true,
};
localDb = new PouchDB(localName);
const remoteDb = new PouchDB(remoteUrl, remoteOptions);
localDb.sync(remoteDb, syncOptions).on("change", function (info) {
console.log(8888, "change", info);
}).on("paused", function (info) {...})...
推荐阅读
- curl - 使用 TFS 的 cURL 和 REST API 安装扩展时出现问题
- android - 无法使用 Flutter 在真正的 Android 设备上获取 Firebase 令牌?
- amazon-web-services - 如何使用在证书管理器中创建的相同 SSL 证书创建另一个云端分发
- java - 如何控制 Apache Kafka 在特定时间发出的消息数量?
- php - 通过 Django 渲染 PHP
- django - Django 的 list_select_related 不显示外键的属性
- azure-cosmosdb - Azure Cosmos DB、Gremlin-API 和原子写入操作
- google-tag-manager - Google 跟踪代码管理器自定义事件(产品页面浏览量)未触发代码
- r - 在 R 中重命名图例值
- javascript - Mac safari set Interval pause when tab is in background