Websocket 是一种双向通信协议,可以在浏览器和服务器之间建立实时的、持久的连接,使得浏览器能够接收实时数据更新。然而,当涉及到安全性和身份验证方面时,WebSocket 实现会产生一些挑战。本篇文章将讨论如何在 Node.js 环境下使用 Hapi.js 登录和认证 Websocket 连接。
前提知识
本文假设您已了解以下内容:
- WebSocket 的工作原理和使用场景
- Node.js 的基本语法和概念
- Hapi.js 的基本知识
WebSocket 认证
使用 WebSocket 时,客户端向服务器发送连接请求并附带一个唯一的标识符或 Token。服务器使用这个标识符验证客户端是否有权连接并与其通信。如果验证成功,服务器将向客户端发送一个确认消息,表示连接已建立。否则,服务器将发送一个错误消息并拒绝连接请求。
在本文中,我们使用 JSON Web Token(JWT)对 WebSocket 进行认证。JWT 是一种基于 JSON 格式的标准,用于在网络应用之间安全地声明数据。JWT 通常由三个部分组成:头部、载荷和签名。头部和载荷是 JSON 对象形式的数据,签名是应用于头部和载荷的哈希值。由于 JWT 是基于标准的,包括 Node.js 和浏览器在内的大多数现代编程语言都提供了 JWT 库和支持。
Hapi.js Websocket 认证
首先,我们需要使用 Hapi.js 插件 hapi-plugin-websocket。
const Hapi = require('hapi'); const WebSocket = require('ws'); const HapiWebSocket = require('hapi-plugin-websocket'); const server = Hapi.server({ port: 3000 }); // 注册websocket插件 await server.register(HapiWebSocket);
接下来,我们需要建立 WebSocket 连接并验证 JWT。
// javascriptcn.com 代码示例 server.websocket('/websocket/{token}', { // 声明此 websocket 只接受 get 请求 only: true, // 定义 websocket 的请求验证 async connected(websocket, request, token) { try { // 验证 token const decodedToken = jwt.verify(token, secret); // 验证成功 websocket.on('message', async (data) => { const payload = JSON.parse(data); // 数据处理逻辑 // 向客户端发送消息 websocket.send(JSON.stringify(responsePayload)); }); } catch (err) { // 验证失败 websocket.send(JSON.stringify({ error: err.message })); websocket.close(); } }, });
在上面的代码中,Websocket 插件的 connected 方法将处理 WebSocket 连接。当客户端尝试连接到 /websocket/{token}
路径时,Hapi.js 将启动 WebSocket 服务器,并将连接的 websocket 对象传递给 connected 方法。connected 方法还接收两个参数:request 和 token。request 包含 HTTP 请求的信息,包括现有的 Cookie、头信息和其他属性。token 是用于验证客户端连接的 JWT。
在 connected 方法中,我们使用 JSON Web Token 验证客户端连接请求。如果 token 无效,则关闭 WebSocket 连接并向客户端发回错误消息。否则,我们向客户端发送 JSON 格式数据。注意发送消息应该使用 websocket.send
方法,而不是 websocket.write
方法。
在 connected 方法返回之前,我们可以定义 on
事件监听 websocket 的消息。在上述例子中,我们假设消息是JSON格式的,并在收到消息后将其解析和处理。responsePayload
是我们传递给客户端的 JSON 格式数据。
完整代码示例
完整的代码示例如下:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const WebSocket = require('ws'); const jwt = require('jsonwebtoken'); const HapiWebSocket = require('hapi-plugin-websocket'); const server = Hapi.server({ port: 3000 }); const secret = 'I love Mary. She is my sunshine.'; async function init() { // 注册websocket插件 await server.register(HapiWebSocket); // 定义websocket服务 server.websocket('/websocket/{token}', { only: true, async connected(websocket, request, token) { try { // 验证token const decodedToken = jwt.verify(token, secret); // 验证成功 websocket.on('message', async (data) => { const payload = JSON.parse(data); // 消息处理逻辑 const responsePayload = { message: 'Hello World!' }; // 向客户端发送消息 websocket.send(JSON.stringify(responsePayload)); }); } catch (err) { // 验证失败 websocket.send(JSON.stringify({ error: err.message })); websocket.close(); } }, }); await server.start(); console.log(`Server running on ${server.info.uri}`); } init();
您可以使用 WebSocket 客户端测试此示例。记得将占位符 {token}
替换为有效的 JWT 令牌。在此示例中,我们使用 JSON 格式的消息向客户端回复“Hello World”!
总结
使用 Hapi.js 对 WebSocket 进行身份验证并不难,只需要了解一些 Node.js 和 JWT 的基本知识即可。通过运用 JWT,我们可以安全地验证 WebSocket 连接并传递身份信息。此技术可用于构建实时通信应用程序,例如多人游戏、聊天、在线市场、股票报价和任何其他需要实时数据更新的应用程序。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653a07b27d4982a6eb3c21f6