2

我正在使用 couchbase mobile 进行应用程序,并且我想使用 facebook 进行身份验证。根据文档,couchbase 提供了自己的身份验证实现,唯一需要的是我从 android facebook 登录流程中检索到的令牌。

Synchronize 类的代码如下所示:

public class Synchronize {

public Replication pullReplication;
public Replication pushReplication;

public static class Builder {
    public Replication pullReplication;
    public Replication pushReplication;

    public Builder(Database database, String url, Boolean continuousPull) {

        if (pullReplication == null && pushReplication == null) {

            URL syncUrl;
            try {
                syncUrl = new URL(url);
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }

            pullReplication = database.createPullReplication(syncUrl);
            pullReplication.setContinuous(true);

            pushReplication = database.createPushReplication(syncUrl);
            pushReplication.setContinuous(true);
        }
    }

    public Builder facebookAuth(String token) {

        if (!TextUtils.isEmpty(token)) {
            Authenticator facebookAuthenticator = AuthenticatorFactory.createFacebookAuthenticator(token);

            pullReplication.setAuthenticator(facebookAuthenticator);
            pushReplication.setAuthenticator(facebookAuthenticator);
        }

        return this;
    }

    public Builder basicAuth(String username, String password) {

        Authenticator basicAuthenticator = AuthenticatorFactory.createBasicAuthenticator(username, password);

        pullReplication.setAuthenticator(basicAuthenticator);
        pushReplication.setAuthenticator(basicAuthenticator);

        return this;
    }

    public Builder addChangeListener(Replication.ChangeListener changeListener) {
        pullReplication.addChangeListener(changeListener);
        pushReplication.addChangeListener(changeListener);

        return this;
    }

    public Synchronize build() {
        return new Synchronize(this);
    }

}

private Synchronize(Builder builder) {
    pullReplication = builder.pullReplication;
    pushReplication = builder.pushReplication;
}

public void start() {
    pullReplication.start();
    pushReplication.start();
}

public void destroyReplications() {
    if (pullReplication != null && pushReplication != null) {
        pullReplication.stop();
        pushReplication.stop();
        pullReplication.deleteCookie("SyncGatewaySession");
        pushReplication.deleteCookie("SyncGatewaySession");
        pullReplication = null;
        pushReplication = null;
    }
}

}

我像这样使用它:

...
public void startReplicationSync(String facebookAccessToken) {

    if (sync != null) {
        sync.destroyReplications();
    }

    final String url = BuildConfig.URL_HOST + ":" + BuildConfig.URL_PORT + "/" + DATABASE_NAME;
    sync = new Synchronize.Builder(databaseManager.getDatabase(), url, true)
            .facebookAuth(facebookAccessToken)
            .addChangeListener(getReplicationChangeListener())
            .build();
    sync.start();

}
...

我的同步网关 json 配置文件:

{
"interface":":4984",       
"adminInterface":":4985",
"log":["REST"],
"facebook":{
  "register" : true
},
"databases":{               
"sync_gateway":{
"server":"http://localhost:8091",
"bucket":"sync_gateway",
"users": {
    "GUEST": {"disabled": false}
},
"sync":`function(doc) {channel(doc.channels);}`
}
}
}

我也试过“GUEST”:{“disabled”:true},没有运气

我的问题是,如果我这样做

pullReplication.setAuthenticator(facebookAuthenticator);
pushReplication.setAuthenticator(facebookAuthenticator);

任何东西都不会从服务器中复制/拉取。但是,如果我不设置身份验证器,则所有内容都会被拉出。是我做错了什么吗?我真的需要使用身份验证器来防止某些文档不会被复制给未经身份验证的用户。

笔记!令牌很好,就好像我正在查看同步网关管理员的用户部分一样,我可以看到我传递给 couchbase facebook 身份验证器的登录用户令牌的正确配置文件 ID。

4

1 回答 1

3

在您提供的同步网关配置中,同步功能function(doc, oldDoc) {channel(doc.channels);}意味着如果同步网关处理的文档在channels字段下包含字符串,则该文档将映射到此/这些通道。让我们假设以下配置文件:

{
  "log": ["CRUD"],
  "databases": {
    "db": {
      "server": "walrus:",
      "users": {
        "GUEST": {"disabled": false, "admin_channels": ["*"]}
      },
      "sync": `
        function sync(doc, oldDoc) {
          channel(doc.channels);
        }
      `
    }
  }
}

如果 channels 字段不存在,则文档将映射到名为undefined. 但是该GUEST帐户可以访问 * 频道(代表所有频道的占位符)。因此,所有未经身份验证的复制都将提取所有文档。现在让我们在配置文件中引入 facebook 登录字段。这一次,使用 facebook 令牌进行身份验证的复制代表默认情况下只能访问该!频道的新用户(观看此截屏视频以了解该!频道,即公共频道https://www.youtube.com/watch?v=DKmb5mj9pMI)。要让用户访问其他频道,您必须在同步函数中使用访问 API 调用(在此处阅读有关所有同步函数 API 调用的更多信息)。

在 facebook 身份验证的情况下,用户的 facebook ID 用于表示用户名。假设文档有一个保存用户 facebook ID ( user_id: FACEBOOK_ID) 的属性,您可以将文档映射到频道并授予用户访问权限。新的同步函数如下所示:

function(doc, oldDoc) {
  channel(doc._id);
  access(doc.user_id, doc._id);
}

您可以使用 Facebook Android SDK 检索用户的 Facebook ID 并保存在文档字段中。

于 2015-12-09T18:28:02.760 回答