medic/cht-conf

Use AuthSession cookie for login instead of basic auth

dianabarsan opened this issue · 3 comments

Describe the issue
We're discussing increasing pbkdf2 iterations for CouchDb.
This will mean that computing the hashed password every time basic auth is used will become a costly server-side operation.

Describe the improvement you'd like
Instead of using basic auth for every request, make one initial _session request, and use the provided AuthSession cookie to authenticate all following requests within one conf run.

Describe alternatives you've considered
None.

I've been working on a prototype for this...

@dianabarsan Here is my very simple test script for the cht-conf version of cookie auth:

This should be a very simple drop in solution for cht-conf which uses rpn in the api file, but it's blocked on #583

const nodefetch = require('node-fetch');

let c;

const getAuthSessionCookie = async () => {

  if (c) {
    return c;
  }

  const headers = new nodefetch.Headers({
    'Content-Type': 'application/json'
  });

  const body = JSON.stringify({ username: 'iterations', password: 'pass' });
  const t0 = performance.now();
  const res = await nodefetch('http://localhost:5988/_session', { headers, method: 'POST', body });
  const t1 = performance.now();
  console.log(`BASIC AUTH: ${t1-t0}`);
  const cookies = res.headers.raw()['set-cookie']
  const cookie = cookies[0];
  const authSessionCookie = cookie.split(';')[0];
  c = authSessionCookie.split('=')[1];

  return c;
};

const makeRequest = async () => {
  const sessionCookie = await getAuthSessionCookie();
  const headers = new nodefetch.Headers({
    'Content-Type': 'application/json'
  });
  headers.append("cookie", `AuthSession=${sessionCookie}`);
  const t0 = performance.now();
  const res = await nodefetch('http://localhost:5988/medic/branding', { headers });
  const t1 = performance.now();
  console.log(`COOKIE AUTH: ${t1-t0}`);
  console.log(res.status);
  const body = await res.json();
  console.log(body);
};

const go = async () => {
  while(true) {
    await makeRequest();
    await new Promise(resolve => setTimeout(resolve, 20000));
  }
};

go();

@dianabarsan I think this is merged and released now - can you confirm?