npm install behalf --save
Behalf mimics the way browsers make requests and manage cookies. It provides session objects that automatically send and store cookies with each request, as well as Express middleware that allows you to automatically load sessions within requests.
var session = behalf.createSession({ host: 'amazon.com' });
session
.requestSecure({
method: 'POST',
uri: '/login',
form: {
email: 'blitz@prolificinteractive.com',
password: 'dogtreats'
}
})
.then(function () {
return session.requestSecure('/wishlist'); // Session automatically sends cookies along
})
.get('body')
.done(doStuffWithWishlistPage);
- behalf.createSession
- behalf.Session.import
- session.export
- session.request
- session.requestSecure
- session.requestJson
- session.requestJsonSecure
jar
- A cookie jar either made withrequest
library'srequest.jar()
method or atough-cookie
jar object. Creates a new one by default.id
- A uuid. Automatically generated by default.userAgent
- A user agent string to send along in the header of each request.host
- Sets a host so that we don't have to repeat it for every request.
Creates a behalf session object from an exported object.
Returns an object containing the session's id
and cookie jar. Useful for serializing and persisting to a database.
Makes a request using the request library, automatically using the stored jar
, host
, and userAgent
. Supports both promises and callbacks, with a response object as the return value.
By default, Behalf will manually follow redirects so that it can consume any cookies that are sent back along the way. To disable this, simply set followRedirect: true
in requestOptions
.
Same as session.request
, except using https
protocol.
Sets the Content-Type
header to "application/json" and adds a json
key to the response object, which contains the parsed body.
Same as session.requestJson
but with HTTPS as the protocol.
The library also includes a set of Express middleware to manage the automatic loading and saving of sessions, which is very useful for applications that wrap around websites (see examples/ folder).
This middleware extracts a session key from the request, then loads a session. Example:
var sessions = new behalf.middleware.sessionManager(
store: new behalf.stores.Redis(),
ttl: 3600000, //1 hour
getKey: function (req) {
return req.headers['session-key'];
}
);
app.use(sessions);
Options:
store
- An instance of a session store. Behalf comes with two:behalf.stores.Memory
andbehalf.stores.Redis
. See "Session Stores" to learn more.ttl
- TTL in milliseconds. Defaults to indefinite TTL.getKey
- A function that extracts and returns the session key from the Express request object.
Now you'll get an object attached to the Express request object under the behalf
property that contains the session context. It has these properties:
key
- The session key, ornull
, extracted with thegetKey
function.session
- The loadedbehalf.Session
instance, ornull
.
In this example, we proxy Amazon's homepage. If the user has logged in using a Behalf session request, the cookies will trigger the site to serve that user's personalized homepage rather than the generic one:
app.get('/', function (req, resp, next) {
req.behalf.session
.request('http://amazon.com')
.done(resp.send.bind(resp), next);
});
This middleware ensures that there will be a session, or throws an error. If no session key is found in the request, it will return a 499
status code. If a key is found but can't be retrieved from the store, a 498
status code is returned.
Example:
app.get('/wishlist', behalf.middleware.requireSession(), function (req, resp, next) {
req.behalf.session
.request('http://amazon.com/account/wishlist')
.done(resp.send.bind(resp), next);
});
Creates a new session. This is useful for providing an endpoint that grants session keys:
app.get('/sessions/new', [
behalf.middleware.generateSession(),
function (req, resp) {
resp.send({
sessionId: req.behalf.session.id
});
}
]);
Behalf includes two session stores, one in-memory and one for Redis.
Options:
config
- Optional. Redis configuration, passed into theredis.createClient
constructor.keyPrefix
- Optional. Prepended to every Redis key that sessions are stored against. Default: "sessions:"
Stores sessions within the memory of the running process. Recommended for development use only.
If you want to use a different kind of database, the interface for a store is very simple. There are 3 required methods: save
, load
, and destroy
.
The save method takes a behalf.Session
instance and an optional TTL, and should return a promise. The promise shouldn't resolve with a value. You should always use the session.export
method to serialize the session instance. Here's a pseudo-example:
MyStore.prototype.save = function (session, ttl) {
var exportObj = session.export();
exportObj.jar = JSON.stringify(exportObj.jar);
return this.db
.insert('sessions', exportObj)
.then(function () {
if (ttl) {
return messageQueue.cancel('destroySession', { id: session.id });
}
})
.then(function () {
return messageQueue.push('destroySession', { id: session.id }, ttl);
})
.return();
}
The load method takes a session ID string as an argument and returns a promise that resolves to a behalf.Session
instance. Use behalf.Session.import
to deserialize the exported object.
MyStore.prototype.load = function (sessionId) {
return this.db
.select('sessions', sessionId)
.tap(function (exportObj) {
exportObj.jar = JSON.parse(exportObj.jar);
})
.then(behalf.Session.import);
}
Takes a session ID string as an argument and returns a promise that resolves with no value:
MyStore.prototype.destroy = function (sessionId) {
return this.db
.delete('sessions', sessionId)
.return();
}
Test your interface by using the test suite:
require('behalf/test/session-store-test')(new MyStore(), 'MyStore');
Run tests using npm test
.