Reputation: 33
I am trying to get the questions for the current user with a request like this:
http://localhost:1337/question/forme
As part of the GET request, I am able to access req.user.username and serve the JSONresponse when accessing it from the browser.
When I try to make the same Socket.get() request from my Angular client.js file, it doesn't work. I also tried to access it using browser console and it fails for socket.get() requests.
Upvotes: 3
Views: 2093
Reputation: 5894
I spent a large time figuring out all the moving parts to get passport working with sails on my blog
I'll repost the relevant parts below, with an additional policy change I made.
I created a passport.js file to manage my passport configuration/strategy registration
/config/passport.js
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findOneById(id).done(function (err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
User.findOne({ email: email}).done(function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Unknown user ' + email }); }
if (user.password != password) { return done(null, false, { message: 'Invalid password' }); }
return done(null, user);
});
}
));
And then I used a policy to verify authentication. It makes use of the passport sessions if a socket request is made.
/api/policies/isAuthenticated.js
module.exports = function(req, res, next) {
// User is allowed, proceed to the next policy,
// or if this is the last policy, the controller
// Sockets
if(req.isSocket)
{
if(req.session &&
req.session.passport &&
req.session.passport.user)
{
//Use this:
// Initialize Passport
sails.config.passport.initialize()(req, res, function () {
// Use the built-in sessions
sails.config.passport.session()(req, res, function () {
// Make the user available throughout the frontend
//res.locals.user = req.user;
//the user should be deserialized by passport now;
next();
});
});
//Or this if you dont care about deserializing the user:
//req.user = req.session.passport.user;
//return next();
}
else{
res.json(401);
}
}
else if (req.isAuthenticated()) {
return next();
}
else{
// User is not allowed
// (default res.forbidden() behavior can be overridden in `config/403.js`)
return res.redirect('/account/login');
}
};
Upvotes: 7
Reputation: 2986
You can inject authentication methods into socket requests. For this just make a little hijack into config/bootstrap.js
.
var passport = require('passport'),
http = require('http'),
initialize = passport.initialize(),
session = passport.session(),
methods = ['login', 'logIn', 'logout', 'logOut', 'isAuthenticated', 'isUnauthenticated'];
module.exports.bootstrap = function(cb) {
sails.removeAllListeners('router:request');
sails.on('router:request', function(req, res) {
initialize(req, res, function() {
session(req, res, function(error) {
if (error) {
return sails.config[500](500, req, res);
}
for (var i = 0; i < methods.length; i++) {
req[methods[i]] = http.IncomingMessage.prototype[methods[i]].bind(req);
}
sails.router.route(req, res);
});
});
});
cb();
};
After this hijack you can use isAuthenticated()
and other methods from Passport in sockets.
And then inject user variable through policies like Scott says.
Upvotes: 1
Reputation: 24948
Sails is great in that it routes socket requests in the same manner as HTTP requests, so that you can hit the same endpoint and execute the same code with either transport. However, there are limits, and you're seeing one here. Passport is Express middleware, and the socket request isn't being handled by Express, so the middleware isn't applied.
I'm no expert on Passport, but I imagine it still works using the session, which is available to your socket request, so I think you could probably handle this in one of two ways:
req
object if it's not already available (i.e. for non-http requests).Upvotes: 0