使用承载授权将PouchDB同步到Cloudant时出错

时间:2019-05-28 14:22:08

标签: javascript oauth pouchdb cloudant

我是一位经验丰富的JavaScript程序员,但是对PouchDB,Cloudant和oAuth还是陌生的。当我尝试使用Bearer Authorization同步PouchDB和Cloudant时,出现错误:

waitForFinish=False

我正在尝试使用PouchDB和Cloudant编写一个演示Web应用程序。我设置了一个IBM帐户。我创建了一项名为Cloudant-xx的服务。我选择了身份验证方法:IBM Cloud IAM(我没有选择“和旧版...”)。我转到了该服务的仪表板,然后1)创建了一个数据库(myDatabase),2)选择了屏幕左侧的头像,然后选择了[CORS],并禁用了CORS(用于开发)。

我回到该服务,选择[服务凭证],并创建了一个新的服务凭证。这给了我一个带有{“ apikey”:“ ELB4lEVA ... IO”,...,“ username”:“ 451c ... 74-bluemix”}}的对象。

我使用curl来获取访问令牌:

"_reader access is required for this request", status: 401

返回了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"

在一个小时内,我将访问令牌复制并粘贴到了我的javascript代码中,运行了该代码,并收到错误消息“此请求需要_reader访问权限”(请参见上文)。我找不到在何处设置_reader访问权限。有谁能够帮助我?谢谢!

{"access_token":"eyJra...6fJns","token_type":"Bearer","expires_in":3600,"expiration":1558965151,"scope":"ibm openid"}

在控制台中,我看到:

    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);

1 个答案:

答案 0 :(得分:1)

我回答了我自己的问题。原来,我正在跟踪过时的示例。在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) {...})...