如何在express和socket.io中使用护照? [英] How to use passport with express and socket.io?

查看:30
本文介绍了如何在express和socket.io中使用护照?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试为我的 node.js 应用程序设置一个基本的身份验证系统.现在我使用 express (3.0.0rc5)、passport (0.1.12) 和 socket.io (0.9.10) 和 Mongoose 作为会话数据的存储.我也一直在玩 everyauth,但我不喜欢使用 Promise.

I am currently trying to set up a basic authentication system for my node.js app. For now I am using express (3.0.0rc5), passport (0.1.12) and socket.io (0.9.10) with Mongoose as Store for session data. I have also been playing around with everyauth but I didn't like to work with promises.

现状:

通过护照(facebook 策略)进行身份验证成功,重定向后在客户端上设置了 session.sid cookie,我可以在我的数据库中看到会话文档.我可以通过 socket.handshake.headers.cookie 访问 socket.io 中的 session cookie.

Authentication through passport (facebook strategy) is successful, a session.sid cookie is set on the client after the redirect and I am able to see a session document in my database. I can access the session cookie in socket.io through socket.handshake.headers.cookie.

如果我正确理解了护照概念,则在成功调用 authenticationpassport.serializeUser 后,我可以将信息添加到会话中.就我而言,最重要的信息是电子邮件,因此我按以下方式设置序列化程序:

If I understood the passport concept correctly, after successful authentication passport.serializeUser is called which enables me to add information to the session. In my case the most important information is the email, so I set the serializer up in the following way:

passport.serializeUser(function(user, done) {
  done(null, user.email);
});

现在我只能使用 socket.io 事件中的 cookie 信息从会话中提取电子邮件地址.

Now I am at the point where I have to use only the cookie information in my socket.io event to extract the email address from the session.

var connect = require('connect'),
    parseSignedCookie = connect.utils.parseSignedCookie,
    cookie            = require('express/node_modules/cookie');

io.on('connection', function(socket) {
    if(socket.handshake.headers.cookie) {
        var cookie = cookie.parse(socket.handshake.headers.cookie);
        var sessionID = parseSignedCookie(cookie['connect.sid'], 'secret');
    }
});

passport.deserializeUser(function(id, done) {
    // so, what is supposed to be done here?
});

所以如果我没记错的话,现在的任务是使用deserializeUser来访问对应的email地址.

So if I am not mistaken, the task is now to use deserializeUser to access the corresponding email address.

我该怎么做?任何指针都非常感谢.

How would I do that? Any pointers are highly appreciated.

推荐答案

这是一个使用 Socket.IO 1.0 和 Express 4.0 的解决方案.它在精神上与帕特里克的回答相似.诀窍在于,由于 Socket.IO 1.0 有一个新的中间件 API,我们可以将 Express 的中间件包装起来并将其放入 Socket.IO 管道中,而无需深入研究会话存储的低级实现.

Here is a solution using Socket.IO 1.0 and Express 4.0. It is similar in spirit to Patrick's answer. The trick is that since Socket.IO 1.0 has a new middleware API, we can wrap Express's middleware and put it into the Socket.IO pipeline without delving into the low-level implementation of the session stores.

// Set up the Session middleware using a MongoDB session store
expressSession = require("express-session");
var sessionMiddleware = expressSession({
    name: "COOKIE_NAME_HERE",
    secret: "COOKIE_SECRET_HERE",
    store: new (require("connect-mongo")(expressSession))({
        url: "mongodb://localhost/DATABASE_NAME_HERE"
    })
});

// Set up the Express server
var app = require("express")()
    .use(sessionMiddleware)
    .use(passport.initialize())
    .use(passport.session())
    // ... more middleware ...
    .listen(8000);

// Set up the Socket.IO server
var io = require("socket.io")(app)
    .use(function(socket, next){
        // Wrap the express middleware
        sessionMiddleware(socket.request, {}, next);
    })
    .on("connection", function(socket){
        var userId = socket.request.session.passport.user;
        console.log("Your User ID is", userId);
    });

变量 sessionMiddleware 是一个函数,旨在直接适应 Express 管道.它只需要三个参数:请求对象、响应对象和回调.

The variable sessionMiddleware is a function that is designed to fit directly into the Express pipeline. It takes exactly three arguments: the request object, the response object, and a callback.

Socket.IO 的管道期望它的中间件只接受两个参数,但是:socket 对象(它包含 socket.request 处的请求对象)和一个回调.幸运的是,sessionMiddleware 不需要响应对象从存储中读取会话,因此我们只需将一个空对象作为第二个参数传递给它.

Socket.IO's pipeline expects its middleware to take only two arguments, however: the socket object (which contains the request object at socket.request) and a callback. Luckily sessionMiddleware does not require the response object to read the session from the store, so we simply pass it an empty object as the second argument.

请注意,下面的一些注释观察到此代码将会话呈现为只读.由于 Socket.IO 没有适当的响应对象,我们失去了这个功能.

Note that some comments below observe that this code renders the session read-only. This is the functionality we lose by not having a proper response object with Socket.IO.

在上面的示例中,我使用了 MongoDB 会话存储 (connect-mongo).您可以使用任何适合您的会话存储.有关会话存储列表,请参阅Connect wiki.

In the above example I use a MongoDB session store (connect-mongo). You can use whatever session store fits your liking. Refer to the Connect wiki for a list of session stores.

这篇关于如何在express和socket.io中使用护照?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆