Users can be authenticated in two ways: over the websocket or over HTTP.
The first option is useful if you're authenticating against a backend database or other resource you control, the second if you're using a third-party service such as Facebook Connect.
Either way, the goal is the same: to update req.session.userId
with the user's unique ID.
This is the best choice if you're authenticating against an internal database or LDAP server, etc.
// server/rpc/app.js exports.actions = function(req, res, ss){ // tell SocketStream to load session data req.use('session'); return { authenticate: function(username, password){ // lookup user in DB, LDAP, etc if (user) { req.session.setUserId(user.id); res(true); } else { res('Access denied!'); } }, logout: function(){ req.session.setUserId(null); } } }
Note: You could just set req.session.userId
manually, but calling the req.session.setUserId()
function saves the session and notifies SocketStream to immediately start sending events for this user (sent using ss.publish.user()
) over the current websocket connection.
Since the same session object is also available over HTTP you may easily authenticate a user by updating req.session.userId
whilst processing a HTTP request.
Let's look at a very simple example by adding the following 'route' to app.js
:
// app.js ss.http.router.on('/authenticateMe', function(req, res) { req.session.userId = 'john'; req.session.save(function(err){ res.serve('main'); }); });
Next, add an RPC action which sends the contents of req.session.userId
over the websocket:
// server/rpc/app.js exports.actions = function(req, res, ss){ // tell SocketStream to load session data req.use('session'); return { getCurrentUser: function(){ res('The current user is ' + req.session.userId); } } };
Now visit http://localhost:3000/authenticateMe
then enter the following command in the browser's console:
ss.rpc('app.getCurrentUser')
And you'll see the following output:
The current user is john
SocketStream integrates well with popular authentication libraries such as Everyauth.
Tip: Don't be tempted to follow the docs on the Everyauth website too closely - they are mainly geared at multi-page apps and/or specific to Express.
Here's an example of a full app which authenticates against Twitter's OAuth service.
To get started, register your new app at https://dev.twitter.com/apps/new
When testing your app supply http://127.0.0.1:3000
as the Callback URL. Change this to the real URL when your app goes into production.
// app.js var http = require('http'), ss = require('socketstream'), everyauth = require('everyauth'); ss.client.define('main', { view: 'app.jade', css: ['libs', 'app.styl'], code: ['libs', 'modules', 'main'] }); ss.http.router.on('/', function(req, res) { res.serve('main'); }); everyauth.twitter .consumerKey('YOUR CONSUMER ID HERE') .consumerSecret('YOUR CONSUMER SECRET HERE') .findOrCreateUser( function (session, accessToken, accessTokenSecret, twitterUserMetadata) { var userName = twitterUserMetadata.screen_name; console.log('Twitter Username is', userName); session.userId = userName; session.save(); return true; }) .redirectPath('/'); ss.http.middleware.prepend(ss.http.connect.bodyParser()); ss.http.middleware.append(everyauth.middleware()); var server = http.Server(ss.http.middleware); server.listen(3000); ss.start(server); // To authenticate visit http://local.host:3000/auth/twitter
Many more details on this and other examples coming soon.