Trouble authenticating to Sync Gateway with Facebook

I’m hoping you can help point me in the right direction. I keep getting unauthorized errors during replication.

My sync config looks like:

{
  "facebook" : { "register": true },
  "interface": "0.0.0.0:4984",
  "adminInterface": "0.0.0.0:4985",
  "log": [
    "Shadow",
    "CRUD+",
    "REST+",
    "Changes+",
    "Attach+"
  ],
  "databases": {
    "sync_gateway": {
      "server": "http://myserver:8091",
      "bucket": "sync_gateway"
    }
  }
}

In my app, the Facebook login ui pops up, I put in my credentials and get back an access_token:

var auth = AuthenticatorFactory.CreateFacebookAuthenticator (access_token);

In db/_user I’m able to see the newly created user.

In my app, I subscribe to the change event handler for push and pull replication.

pull.Changed += ReplicationProgress;
push.Changed += ReplicationProgress;

Which gets caught as unauthorized here:

private void ReplicationProgress(object replication, ReplicationChangeEventArgs args)
        {
            if (args.Source.LastError != null)
            {
                var httpError = args.Source.LastError as HttpResponseException;
                if (httpError != null && httpError.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    LoginValid = false;

And shows up in the log as:

2015-07-21T16:38:05.493Z HTTP:  #340: GET /sync_gateway/                                      
2015-07-21T16:38:05.493Z HTTP: #340:     --> 401 Login required  (2.3 ms)                     
2015-07-21T16:38:05.682Z HTTP:  #341: GET /sync_gateway/                                      
2015-07-21T16:38:05.682Z HTTP: #341:     --> 401 Login required  (1.7 ms)                     
2015-07-21T16:38:05.857Z HTTP:  #342: GET /sync_gateway/_session                              
2015-07-21T16:38:06.068Z HTTP:  #343: GET /sync_gateway/_session                              
2015-07-21T16:38:06.253Z HTTP:  #344: POST /sync_gateway/_facebook                            
2015-07-21T16:38:06.449Z HTTP:  #345: POST /sync_gateway/_facebook                            
2015-07-21T16:38:06.899Z HTTP:  #346: GET /sync_gateway/_local/b675658c09c4a0649334bb432c26809
acae4f92e                                                                                     
2015-07-21T16:38:06.900Z HTTP: #346:     --> 401 Login required  (2.2 ms)                     
2015-07-21T16:38:07.065Z HTTP:  #347: GET /sync_gateway/_local/64cb8db244e37ab0461be80437f3685
b37cb4cdb                                                                                     
2015-07-21T16:38:07.066Z HTTP: #347:     --> 401 Login required  (2.2 ms) 

Am I missing a step somewhere? From what I’ve read, I think all I need to do is call CreateFacebookAuthenticator( access_token) and the rest should be handled by Couchbase Lite/Sync Gateway.

I also put request to the new user with a known good admin_channels.

Thanks for your help.

@jamiltz can you help here please?

Yeah, can someone please help? :slight_smile:

So as a work around I’m manually using setCookie on the replicator.

Facebook Auth using Couchbase Lite .net

  • Setup sync gateway config

    "{ "facebook": { "register": true }}"
    
  • Create a webservice on the same sever as sync gateway to interact with the sync gateway Admin REST API

  • App pops up Facebook UI login dialog and get’s an access_token

  • App adds authenication to replication

    var auth = AuthenticatorFactory.CreateFacebookAuthenticator(access_token);
    push.Authenticator = auth;
    pull.Authenticator = auth;
    pull.Changed += ReplicationProgress;
    push.Changed += ReplicationProgress;
    pull.Start();
    push.Start();

  • couchbase lite creates user on sync gateway??

  • pull.Changed event triggers ReplicationProgress

  • Lack of session cookie throws System.Net.HttpStatusCode.Unauthorized

  • so get a session

    • Send Facebook Id to webservice which sends Facebook Id to sync gateway :4985/{db}/_session
    • Sync gateway returns session cookie info as json body to Webservice:
"{
"cookie_name": "SyncGatewaySession",
"expires": "2015-07-24T18:18:35.905685517Z",
"session_id": "c3be1c8f693440308b32cc32c3fae1938f613f9f"
}"
  • Webservice returns session cookie info to App
  • Uninitialize replicator
  • Replace replication with new replication, only this time setCookie
  "push.SetCookie (session ["cookie_name"].ToString (), 
  				session ["session_id"].ToString (), 
  				"/", 
  				DateTime.Parse (session ["expires"].ToString ()), 
  				false, false);
  pull.SetCookie (session ["cookie_name"].ToString (), 
  				session ["session_id"].ToString (), 
  				"/",
  				DateTime.Parse (session ["expires"].ToString ()), 
  				false, false);"

.

  • Since Replication usually is triggered multiple times while getting session, set boolean to prevent grabbing more than one session and needlessly re-initializing the replicator.

Let me know if I’m doing something egregiously wrong, thanks! :slight_smile:

Hey @ksmith,

Sorry for the delay in replying.
The replication should not return a 401 Unauthorized after GET /:db/_local/:checkpoint.

Using the setCookie seems to have solved the issue.

@kanundrum is having the same issue I think.

Are you using a reverse proxy by any chance that could result in having an invalid path in the cookie returned?

James

Hi @jamiltz,

Thanks for your reply, I read the @kanundrum thread, it does seem similar.

I’m not using a reverse proxy.

I’ll install Charles Proxy and poke around.

Thanks!