Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PouchDb 7 : authentication doesn't work anymore #239

Open
jbrun opened this issue Jun 25, 2018 · 20 comments
Open

PouchDb 7 : authentication doesn't work anymore #239

jbrun opened this issue Jun 25, 2018 · 20 comments

Comments

@jbrun
Copy link

jbrun commented Jun 25, 2018

Context

After updated from pouchdb 6.4.2 to 7.0.0 I have some troubles with authentication.
This code works fine before.
this._remotePouchDB.logIn(login, password).then(function (response) {
self._pouchDB.replicate.from(self._remotePouchDB).on('complete', function (info) {
...
}
}
After upgrading, the login phase works already well but when I replicate from, I have an 401 error :
{error: "unauthorized", reason: "one of _design, _reader is required for this request", status: 401, name: "unauthorized", message: "one of _design, _reader is required for this request"}

Your Environment

  • Version of PouchDB Authentication: 1.1.3
  • Version of PouchDB: 7.0.0
  • Platform name and version: Chrome
  • Operating System and version: Windows
  • Server: Cloudant
@ptitjes
Copy link
Collaborator

ptitjes commented Jun 26, 2018

Hi @jbrun.

It was expected as the ajax mechanism has changed. I guess you went to upgrade a little too quickly.

I have a work-in-progress here : #238. It is working correctly on Node.js but I fail to have the whatwg-fetch polyfills to work in the browser tests. If you have any idea how to fix this, please contribute. Thanks.

@tiaod
Copy link

tiaod commented Jul 9, 2018

This works for me:

const db = new PouchDB('http://couchdb:5984/mydb',{
  fetch(url, opts){
    opts.credentials='include'
    return PouchDB.fetch(url, opts)
  }
})

@jbrun
Copy link
Author

jbrun commented Jul 10, 2018

Hi @tiaod

I tried your solution but I have a error :
error TS2345: Argument of type '{ fetch(url: any, opts: any): any; }' is not assignable to parameter of type 'DatabaseConfiguration'. Object literal may only specify known properties, and 'fetch' does not exist in type 'DatabaseConfiguration'. error TS2339: Property 'fetch' does not exist on type 'Static'.

@tiaod
Copy link

tiaod commented Jul 10, 2018

@jbrun That seems like a TypeScript error. I'm not using TypeScript and it works fine :)

@jbrun
Copy link
Author

jbrun commented Jul 12, 2018

I have the same problem with this time pouchdb 6.4.3 and safari on ios 11.4.1

Does anyone else have it?

@jknowlesdev
Copy link

jknowlesdev commented Aug 4, 2018

Using the solution suggested by @tiaod, this worked for me in TypeScript/Angular 6.0.8:

(window as any).global = window;
import { Injectable } from '@angular/core';
import * as PouchDB from 'pouchdb/dist/pouchdb';
import PouchAuth from 'pouchdb-authentication';

PouchDB.plugin(PouchAuth);

@Injectable({
  providedIn: 'root'
})
export class PouchdbService {
     private _pouchDB = new PouchDB('http://localhost:5984/test', {
         fetch(url, opts) {
             opts.credentials = 'include';
             return PouchDB.fetch(url, opts);
          } 
      });
     constructor() { }
}

@NiloCK
Copy link
Contributor

NiloCK commented Aug 5, 2018

@jbrun Try manually asserting the correct type. Note the as PouchDB.Configuration.RemoteDatabaseConfiguration. Working for me now with pouchdb-browser@7.0.0 and pouchdb-authentication@1.1.3

import pouch from 'pouchdb-browser';

new pouch(
    remote_couch_url + dbName,
    {
        fetch(url: any, opts: any) {
            opts.credentials = 'include';
            return (pouch as any).fetch(url, opts);
        }
    } as PouchDB.Configuration.RemoteDatabaseConfiguration
)

@martinhbramwell
Copy link

@tiaod

Pardon me for being thick-skulled, but...

Where (or how) are you supplying the user name and password in that example?

@barbalex
Copy link

barbalex commented Oct 12, 2018

Above solution may be nice if you work with PouchDb directly. But I use RxDb. So it is RxDB that creates the pouches.

Therefore I have no idea how to get my app working again if #238 is not merged :-(

@ptitjes
Copy link
Collaborator

ptitjes commented Oct 13, 2018

@barbalex #238 will not avoid you from tweaking the PouchDB constructor options as @NiloCK does. As you've discovered, we need pouchdb/pouchdb#7395 to get released to avoid that (in 7.1.0, I believe).

@barbalex
Copy link

@ptitjes thanks for your help and for investing in this great project.

Problem is: I do not know how to apply #239 (comment) as the pouches are not created by myself but rather by rxdb.

I am not sure but I believe I would have to tweak rxdb to apply @NiloCK 's trick to tweak PouchDB...

@ptitjes
Copy link
Collaborator

ptitjes commented Oct 14, 2018

@barbalex Well, I just took a 30 seconds look at RxDB (which seems to be a nice library btw) documentation and I found that you can provide a pouchSettings option to the RxDB.create() method. With that you should be able to provide a fetch replacement (see the PouchDB options) just as @NiloCK does. Hope this helps.

@barbalex
Copy link

barbalex commented Oct 14, 2018

@ptitjes Thanks for pointing that out. It took me a little more than 30 seconds but after a while I actually did realize that too :-)

Unfortunately that alone has not solved my problem: pubkey/rxdb#840 (comment).

@niarm
Copy link

niarm commented Oct 22, 2018

I know this is a dirty hack, but the following worked for me with pouchdb 7.0:

let db = new PouchDB('http://someAdress',<any>{
      fetch: (url, opts) => {
        opts.headers.set('some_key', 'value');
        opts.credentials='include';
        return (<any>PouchDB).fetch(url, opts);
      }
  }

@tiangolo
Copy link

Here's my trick to login with session Cookies (as with pouchdb-authentication). It also works with Couchbbase Sync Gateway.


I'm using Couchbase Sync Gateway, it prepends the database name in the URL before the _session endpoint. To be able to use it with the different endpoint that pouchdb-authentication is not expecting (and to overcome this issue) I'm logging in manually to get the session Cookie. The important thing is to use opts.credentials = 'include'; also when sending the name and password, e.g. with fetch:

const myHeaders = new Headers();

myHeaders.append('Content-Type', 'application/json');

fetch('http://example.com:4984/myDb/_session', { method: 'POST', body: '{"name": "myusername", "password": "supersecret"}', headers: myHeaders, credentials: 'include' })

That's how I tested it, but I'm actually using axios, so in my app it looks like this:

axios.post('http://example.com:4984/myDb/_session', { name: 'myusername', password: 'supersecret' }, { withCredentials: true })

The only difference between Couchbase Sync Gateway and CouchDB for the session would be changing the URL from http://example.com:4984/myDb/_session to http://example.com:5984/_session. Namely, the myDb and the port.

And then I'm using @tiaod trick, with @niarm update for TypeScript plus a little update so that TSLint doesn't complain about angle brackets type assertions:

let db = new PouchDB('http://example.com/myDb:4984', {
    fetch(url, opts) {
      opts.credentials = 'include';
      return (PouchDB as any).fetch(url, opts);
    }
  } as any);

As by that point I already have the session Cookie, I'm not adding any additional headers for authorization. That way, using the cookie, I can have persistent sessions and I don't have to ask for the users' credentials everytime they open the app. And I'm not saving the username and password locally in localStorage or something similar.

@Nodragem
Copy link

Nodragem commented Dec 8, 2018

I am not sure I understand why it takes long to make the logIn() function work again. Is it because of some dependencies?

I am using this to log in at the moment:

fetch('http://localhost:5984/_session', {
  method: 'post',
  headers: {
    'Accept': 'application/json',
    'Host': 'localhost:5984',
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  credentials:"include", // SUPER IMPORTANT!
  body: "name=" + user.name + "&password=" + user.password

}).then(function(response) {
  if (!response.ok) {
    throw Error(response.statusText);
  }
  // Read the response as json.
  return response.json();
})
.then(function(responseAsJson) {
  // Do stuff with the JSON
  console.log("POST _session");
  console.log(responseAsJson);
  connectWithDatabase();
})
.catch(function(error) {
  console.log('Looks like there was a problem: \n', error);
});

In connectWithDatabase(), I make sure that I use the opts.credentials = 'include' when I request a database to the server so that the cookie is sent over with my request.

IMPORTANT EDIT: the line credentials: 'include' should also be included in the POST request that creates the session (see SUPER IMPORTANT tag in the above code). Otherwise, some weird behaviour happen. Waht happened to me is that the cookie authentication was working for a while; then the CouchDB server stopped to send the cookie for no reason. I found out that adding this line solved the issue.

@ldelacroixjc
Copy link

@barbalex could you please help me to set up this plug in with RxDB. please

@barbalex
Copy link

barbalex commented Apr 6, 2019

@Idelacroixjc
Sorry to say I did not manage as you can see here pubkey/rxdb#840

@detygon
Copy link

detygon commented Jun 18, 2019

@barbalex Hi! I had the same issue. My solution was to pass the username and password in the remote DB URL.

const username = process.env.DB_USERNAME
const password = process.env.DB_PASSWORD

myCollection.sync({ remote: `https://${username}:${password}@remote-url.com` })

I hope it helps.

@SinanGabel
Copy link

Authentication to couchdb 2.3.x with pouchdb 7.1.1 works very fine.

Can this issue and #243 be closed, or am I missing something?

Thank you in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests