Аутентификатор Couchbase для Facebook

Я использую мобильный телефон Couchbase для приложения и хочу использовать 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);

Ничего никогда не будет реплицировано или извлечено с сервера. Однако, если я не устанавливаю аутентификатор, все вытаскивается. Это что-то, что я делаю неправильно? Мне действительно нужно использовать аутентификатор, чтобы предотвратить репликацию некоторых документов для неаутентифицированных пользователей.

Примечание! Токен хорош, как будто я смотрю в разделе пользователей администратора шлюза синхронизации, я вижу правильный идентификатор профиля токена пользователя, вошедшего в систему, который я передал аутентификатору Facebook на диване.


person sica09    schedule 07.12.2015    source источник


Ответы (1)


В предоставленной вами конфигурации Sync Gateway функция синхронизации имеет значение function(doc, oldDoc) {channel(doc.channels);}, что означает, что если документ, обработанный Sync Gateway, содержит строку(и) в поле channels, документ будет сопоставлен с этим/этими каналами. Предположим, что у нас есть следующий файл конфигурации:

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

Если поле каналов не существует, документ будет сопоставлен с каналом с именем undefined. Но учетная запись GUEST имеет доступ к каналу * (заполнитель для представления всех каналов). Таким образом, все неаутентифицированные репликации будут извлекать все документы. Давайте теперь представим поле входа в facebook в файле конфигурации. На этот раз репликации, аутентифицированные с помощью токена facebook, представляют нового пользователя, который по умолчанию имеет доступ только к каналу ! (посмотрите этот скринкаст, чтобы понять канал !, также известный как общедоступный канал https://www.youtube.com/watch?v=DKmb5mj9pMI). Чтобы предоставить пользователю доступ к другим каналам, вы должны использовать вызов API доступа в функции синхронизации (подробнее обо всех вызовах API функции синхронизации читайте здесь).

В случае аутентификации через facebook идентификатор пользователя в facebook используется для представления имени пользователя. Предположим, что у документа есть свойство, содержащее идентификатор пользователя facebook (user_id: FACEBOOK_ID), вы можете сопоставить документ с каналом и предоставить пользователю доступ к нему. Новая функция синхронизации будет выглядеть так:

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

Вы можете получить идентификатор Facebook пользователя с помощью Facebook Android SDK и сохранить его в поле документа.

person jamiltz    schedule 09.12.2015
comment
Большое спасибо! это действительно помогло мне! Ваше здоровье! - person sica09; 15.12.2015
comment
@jamiltz Итак, если я добавлю все документы в "!" канал с channel("!"), любой пользователь facebook сможет получить эти документы? Нужна ли мне дополнительная конфигурация? - person falsecrypt; 06.02.2016