pouchdb-community / pouchdb-authentication

User authentication plugin for PouchDB and CouchDB.
Apache License 2.0
775 stars 118 forks source link

PouchDb auth cookie does not auto-refresh after 10 minutes. #266

Open willemodendaal opened 3 years ago

willemodendaal commented 3 years ago

I use db.login() to log the user in, do some operations (that work fine). Then I wait 10 minutes and try again with the same db instance, but then the calls fail with HTTP 401 Unauthorized.

I don't see any traffic in Chrome's "Network" tab to indicate that tokens were refreshed.

This is what my CouchDb ini file looks like (maybe I'm missing something here?)

[couchdb] 
single_node=true ; We set this, so that system dbs are created automatically.

[httpd]
enable_cors = true

[chttpd]
port = 31986

[cors]
credentials = true
origins = http://localhost:3000, https://localhost:31984

My javascript code that connects to the remote couchDb looks as follows. configureRemoteCouch and loginToRemoteCouch is only called once by my code, and from there I use the same remoteCouch instance:

import PouchAuth from 'pouchdb-authentication';
PouchDB.plugin(PouchAuth);

let remoteCouch = null;
function configureRemoteCouch(dbName) {
    console.log('Configuring remote couchDb connection...');
    remoteCouch = new PouchDB(
        `http://localhost:31986/${dbName}`,
        {
            skip_setup: true
        });
}

function loginToRemoteCouch(userName, password) {
    console.log('Login local user to remote couchDb family db...';
    remoteCouch.logIn(userName, password, function (err, response) {
        if (err) {
            console.error(err);
        }
        else {

            // All good, do nothing.
        }
    });
}

The javascript code that pushes documents to the local pouchDb and then replicates to the remote looks as follows:

    const createDbDocument = async () => {
        if (!familyDbCreated) return;

        console.log('Save document to local pouchDb...');
        const localPouchDb = new PouchDB(state.familyDbName);
        await localPouchDb.post({   // Some random document. This works fine every time.
            timestamp: new Date()
        });

        console.log('Start replication...');
        localPouchDb.replicate.to(remoteCouch); // This fails if I try after 10 minutes.
        localPouchDb.replicate.from(remoteCouch);
        console.log('Replicated.');
    }

... this is the code where I see the problem. It works within the 10 minute period, but not once the period has elapsed.

Expected Behavior

I'd expect all calls to succeed. The first calls, done immediately after logging in, as well as additional calls after 10 minutes of inactivity.

Current Behavior

Calls made after 10 minutes fail with HTTP 401.

Request URL: http://localhost:31986/familydb2020o11o18t13o14o55o226z/_local/gg95SIxnSDNYZ7a5zCoYPA%3D%3D?
Request Method: GET
Status Code: 401 Unauthorized
Remote Address: [::1]:31986
Referrer Policy: strict-origin-when-cross-origin

Request headers:
GET /familydb2020o11o18t13o14o55o226z/_local/gg95SIxnSDNYZ7a5zCoYPA%3D%3D HTTP/1.1
Host: localhost:31986
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: "Chromium";v="86", "\"Not\\A;Brand";v="99", "Google Chrome";v="86"
accept: application/json
DNT: 1
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
content-type: application/json
Origin: http://localhost:3000
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,af;q=0.7

Response headers:
HTTP/1.1 401 Unauthorized
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: content-type, cache-control, accept-ranges, etag, server, x-couch-request-id, x-couch-update-newrev, x-couchdb-body-time
Cache-Control: must-revalidate
Content-Length: 78
Content-Type: application/json
Date: Wed, 18 Nov 2020 13:28:15 GMT
Server: CouchDB/3.1.1 (Erlang OTP/20)
X-Couch-Request-ID: dd77fc67a4
X-CouchDB-Body-Time: 0

Your Environment

willemodendaal commented 3 years ago

I wasn't sure if I should re-use the remote PouchDb instance (eg. keep a "singleton"), but I did a little experiment, where I only do db.login once, but create a brand new remote instance every time I do a db.replicate.to. When I did this, the _session api was called every time with username and password. So it "worked", but made cookie auth besides-the-point, because it gets a new AuthSession cookie on every call.

SinanGabel commented 3 years ago

You can try the following in local.ini settings:

[couch_httpd_auth]
allow_persistent_cookies = true
; 1 day = 24 * 60 * 60 = 86400 seconds (set timeout to at least 10 minutes but according to your needs)
timeout = 86400
require_valid_user=true