I develop an app with Ionic where each user got its own PouchDB database synchronise with its own remote CouchDB database. I use couch_peruser=true so any user that want to access its database need to authenticate. This system is easy to do if we store the username & password locally or if we ask the user to give them anytime a sync is needed but none of these options are good (security concern or non user-friendly).
I came with those two options, but none is working:
1) The best option that came to me was to use Cookie Authentication, just save the token locally and use it, but unfortunately to connect with the token couchdb ask to use the header :
Cookie: AuthSession={TOKEN}
But this is not possible because it is a non-authorized header (unsafe) and is rejected by the browser.
2) Second option is to use couchdb Proxy Authentication but it is the same as saving the username and password as the token is valid forever.
Is there any way other way of handling authentication ? I was thinking to use an alternative users database, generate a fake password & username then send this credential to be saved into the user app. In this case if the security is compromise the user can change its password so the server can change the second password too (in the same way we revoke a token), but then there is still a problem because with the stolen credential it is always possible to access directly to the couchdb database without being seen..
If you write a Progressive Web App, the Cookie Authentication is great for this, because the browser handles it for you. Use the pouchdb-authentication to log in directly to CouchDB.
On the CouchDB side, configure the Cookies as persistent, and put some longer lifetime on it. You can set it to 2 weeks, for example, so your users will only be asked for the password if they haven't logged in for two weeks.
The cookie TTL is automatically refreshed once a certain threshold is reached (I recall it's at half of the cookie TTL, so it would be refreshed if the cookie is more than a week old).
CouchDB is built for the web, so you can take advantage of it. ;-)
Thanks for your help, i was not able to use couchdb-auth-proxy so I ended up with the following solution that has the advantage to prevent direct access to couchdb :
1) Create a node server to authenticate the user, if auth successful then return couchdb token to the app for cookie authentication
2) Create a node server used only as a couchdb proxy using node-http-proxy
with the following code :
(it is required that this router code come very early in the express middleware otherwise it might change the response and pouchdb sync does not work, so place it before app.use(bodyParser.json()) )
router.all('/*', (req: Request, res: Response, next: NextFunction) {
let token = req.get('X-Auth-Cdb-Token');
let httpProxy = require('http-proxy');
const proxy = httpProxy.createProxyServer({
target: target,
});
req.headers['Cookie'] = 'AuthSession='+token
proxy.web(req, res);
});
3) In your app set the pouchdb remote database with the following header :
remoteDB = new PouchDB(url, {
skip_setup: true,
ajax: {
headers: {
'X-Auth-Cdb-Token': couchdbToken
},
withCredentials: false
}
})
来源:https://stackoverflow.com/questions/48224105/one-database-per-user-security