为什么在Sails.js,Angular.js和Passport.js中为套接字请求定义了`req.user`?

时间:2014-07-26 18:02:33

标签: angularjs sails.js passport.js

我正在尝试通过以下请求为当前用户提出问题:

http://localhost:1337/question/forme

作为GET请求的一部分,我可以访问req.user.username并在从浏览器访问时提供JSONresponse。

当我尝试从我的Angular client.js文件发出相同的Socket.get()请求时,它不起作用。我还尝试使用浏览器控制台访问它,它对socket.get()请求失败。

3 个答案:

答案 0 :(得分:7)

我花了很长时间弄清楚所有活动部件,让我的blog

上的护照与风帆一起工作

我将重新发布以下相关部分,并对我做出额外的政策更改。

我创建了一个passport.js文件来管理我的护照配置/策略注册

/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);
        });
    }
)); 

然后我使用策略来验证身份验证。如果发出套接字请求,它会使用护照会话。

/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');
    }
};

答案 1 :(得分:1)

您可以将身份验证方法注入套接字请求。为此,只需劫持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();
};

在此次劫持之后,您可以在套接字中使用isAuthenticated()和Passport中的其他方法。

然后通过像Scott这样的政策注入用户变量。

答案 2 :(得分:0)

Sails非常棒,因为它以与HTTP请求相同的方式路由套接字请求,因此您可以使用任一传输命中相同的端点并执行相同的代码。但是,有限制,你在这里看到一个。 Passport是Express中间件,Express不处理套接字请求,因此不应用中间件。

我不是Passport的专家,但我认为它仍然可以使用会话, 可用于您的套接字请求,所以我认为您可以通过以下两种方式之一处理:

  1. 从控制器操作中的基础会话变量中读取用户名
  2. 使用策略将“user”应用于req对象(如果尚未提供)(即非http请求)。