如何使用 Node.js/Express + Passport + Websockets 进行身份验证?

Posted

技术标签:

【中文标题】如何使用 Node.js/Express + Passport + Websockets 进行身份验证?【英文标题】:How to authenticate with Node.js/Express + Passport + Websockets? 【发布时间】:2016-08-15 10:46:18 【问题描述】:

我正在构建一个angular2-login-seed,它使用 Passport.js 和 OAuth 策略进行身份验证。显然,使用这些工具进行身份验证的默认方法是使用 express 签名的 HTTP cookie。据我所知,Passport 管理实际的 Set Cookie 标头,以便 express 可以通过 request.isAuthenticated() 验证每个后续请求,并通过 req.session.passport.dataHere 访问护照设置的数据。

我想通过 websocket 将实时数据合并到应用程序中。这当然意味着从服务器到客户端的套接字流。这种通信完全独立于常规的 HTTP 服务器请求含义:

    不包含所有HTTP请求都包含的HTTP cookie

    Express 不代理与套接字的交互,它通过后端使用的任何实现(sock.js、socket.io)进行管理

这使得在表达 HTTP 请求和发送到后端的 websocket 数据之间简化身份验证变得很困难,因为它们是单独的通信方法。

根据我的研究,这给我留下了两个选择。其中之一是使用library 让我的套接字实现(最好是sock.js 而不是socket.io,但我需要做更多的研究)访问快速会话。然后我可以根据需要验证套接字连接。问题是我不知道如何将 express cookie 从前面放入流中,因为 javascript 无法访问它(仅 HTTP cookie)。

我看到人们跳到的另一个常见解决方案是使用 JWT(JSON Web 令牌)。围绕此的实现将 JWT 存储在前端的本地存储中。这样 SPA(在我的例子中是 Angular2 服务)可以在每次请求“无状态”服务器身份验证时发送它,我们也可以通过 websocket 发送它来验证 websocket 连接(前端 JS 显然可以访问本地存储) .在考虑此实现时会想到几件事:

    是否可以让 Passport OAuth 策略使用 JWT 而不是常规会话信息?这需要什么修改?据我所知,Passport 策略使用某种形式的 OAuth1 或 OAuth2 父策略进行身份验证,默认使用 cookie。

    将这些重要信息存储在本地存储中会使应用程序面临安全漏洞(XSS、CSRF 等)

    如果是这样,我见过的最常见的解决方法是将 JWT 存储在 cookie 中,这样它就不会那么容易被访问、欺骗或伪造。然而,这让我回到了使用 JWT 之前的位置,所以还不如不要打扰。

    这是否意味着我必须在后端使用某种状态管理存储(例如 Redis)来管理 JWT 主体的身份验证和解码? (我对 Redis 等一无所知)。

在服务器 HTTP 请求和套接字数据之间连接身份验证的想法很奇怪,但对于正确验证套接字连接似乎至关重要。我有点惊讶不存在更简单的方法。我已经进行了一些研究,并看到了诸如socketio-jwt、express-jwt 等内容,但是我不知道这是否是我的 Passport 策略的可管理过渡,或者是否更容易打开快速会话数据到套接字实现,或者如果我做错了!

任何帮助或指导将不胜感激。

【问题讨论】:

【参考方案1】:

然后我可以根据需要验证套接字连接。问题是我不知道如何将 express cookie 从前面放入流中,因为 javascript 无法访问它(仅 HTTP cookie)。

使用express-socket.io-session,会话身份验证是在握手时完成的,握手是一个 http 请求,所以即使你的 cookie 是 http-only,它也可以工作。 (本人亲测)

【讨论】:

以上是关于如何使用 Node.js/Express + Passport + Websockets 进行身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Node.js、Express 和 Mongoose 进行身份验证?

如何解析 node.js、express.js、mysql2 中“rows”对象的数据

如何在超级终端中停止运行 Node.js (Express) 服务器

如何使用Node.js Express执行Python函数[复制]

Node.js / Express / Mongoose - 如何发送 JSON 以及对象视图?

如何在 Node.js / Express.js 中将中间件放在它自己的文件中