Authentication with node.js, nano and CouchDB
Is there a way to change the config para开发者_开发问答meters in nano after initialization? I'd like to init nano with:
nano = require('nano')('http://127.0.0.1:5984')
and later change user and password, after a user submits the login form. I always get an error:
nano.cfg.user = params.user.name
TypeError: Cannot set property 'user' of undefined
Or should I fork nano and write an auth function to adjust the values?
I can't test it right now, but, looking at the sources, you can note two things:
- that configuration is exposed as
config
, notcfg
; - that the config option for connection is
url
.
Then I think you need to set the url configuration option to a new value with authentication parameters:
nano.config.url = 'http://' + params.user.name + ':' + params.user.password + '@localhost:5984';
Or you can keep a configuration object as in couch.example.js and do something like:
cfg.user = params.user.name;
cfg.pass = params.user.password;
nano.config.url = cfg.url;
UPDATE: here's a complete example:
var cfg = {
host: "localhost",
port: "5984",
ssl: false
};
cfg.credentials = function credentials() {
if (cfg.user && cfg.pass) {
return cfg.user + ":" + cfg.pass + "@";
}
else { return ""; }
};
cfg.url = function () {
return "http" + (cfg.ssl ? "s" : "") + "://" + cfg.credentials() + cfg.host +
":" + cfg.port;
};
var nano = require('nano')(cfg.url()),
db = nano.use('DB_WITH_AUTH'),
docId = 'DOCUMENT_ID';
function setUserPass(user, pass) {
cfg.user = user;
cfg.pass = pass;
nano.config.url = cfg.url();
}
db.get(docId, function (e, r, h) {
if (e) {
if (e['status-code'] === 401) {
console.log("Trying again with authentication...");
setUserPass('USENAME', 'PASSWORD');
db.get(docId, function (e, r, h) {
if (e) {
console.log("Sorry, it did not work:");
return console.error(e);
}
console.log("It worked:");
console.log(r);
console.log(h);
});
return;
}
console.log("Hmmm, something went wrong:");
return console.error(e);
}
console.log("No auth required:");
console.log(r);
console.log(h);
});
The authentication can be send as part of the http header:
if(cfg.user && cfg.pass) {
req.headers['Authorization'] = "Basic " + new Buffer(cfg.user+":"+cfg.pass).toString('base64');
}
The username and password can be set with a 'auth'-function:
function auth_db(user, password, callback) {
cfg.user = user;
cfg.pass = password;
return relax({db: "_session", method: "GET"}, callback);
}
精彩评论