WebSocket 鉴权策略与技巧详解

WebSocket 作为实时通信的利器,越来越受到开发者的青睐。然而,为了确保通信的安全性和合法性,鉴权成为不可或缺的一环。本文将深入探讨 WebSocket 的鉴权机制,为你呈现一揽子的解决方案,确保你的 WebSocket 通信得心应手。

alt

使用场景

WebSocket 鉴权在许多场景中都显得尤为重要。例如,实时聊天应用、在线协作工具、实时数据更新等情境都需要对 WebSocket 进行鉴权,以确保只有合法的用户或服务可以进行通信。通过本文的指导,你将更好地了解在何种场景下使用 WebSocket 鉴权是有意义的。

WebSocket 调试工具

要调试 WebSocket,那就需要一个好的调试工具,这里我比较推荐 Apifox。它支持调试 http(s)、WebSocket、Socket、gRPCDubbo 等多种协议的接口,这使得它成为了一个非常全面的接口测试工具!

alt

常见方法

方法 1:基于 Token 的鉴权

WebSocket 鉴权中,基于 Token 的方式是最为常见和灵活的一种。通过在连接时携带 Token,服务器可以验证用户的身份。以下是一个简单的示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

const WebSocket = require('ws');

const server = new WebSocket.Server({ port: 3000 });

server.on('connection', (socket, req) => {

    const token = req.headers['sec-websocket-protocol'];

     

    // 验证token的合法性

    if (isValidToken(token)) {

        // 鉴权通过,进行后续操作

        socket.send('鉴权通过,欢迎连接!');

    } else {

        // 鉴权失败,关闭连接

        socket.close();

    }

});

方法 2:基于签名的鉴权

另一种常见的鉴权方式是基于签名的方法。通过在连接时发送带有签名的信息,服务器验证签名的合法性。以下是一个简单的示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

const WebSocket = require('ws');

const crypto = require('crypto');

const server = new WebSocket.Server({ port: 3000 });

server.on('connection', (socket, req) => {

    const signature = req.headers['x-signature'];

    const data = req.url + req.headers['sec-websocket-key'];

     

    // 验证签名的合法性

    if (isValidSignature(signature, data)) {

        // 鉴权通过,进行后续操作

        socket.send('鉴权通过,欢迎连接!');

    } else {

        // 鉴权失败,关闭连接

        socket.close();

    }

});

方法 3:基于 IP 白名单的鉴权

在某些情况下,你可能希望限制 WebSocket 连接只能来自特定 IP 地址范围。这时可以使用基于 IP 白名单的鉴权方式。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

const WebSocket = require('ws');

const allowedIPs = ['192.168.0.1', '10.0.0.2'];

const server = new WebSocket.Server({ port: 3000 });

server.on('connection', (socket, req) => {

    const clientIP = req.connection.remoteAddress;

     

    // 验证连接是否在白名单中

    if (allowedIPs.includes(clientIP)) {

        // 鉴权通过,进行后续操作

        socket.send('鉴权通过,欢迎连接!');

    } else {

        // 鉴权失败,关闭连接

        socket.close();

    }

});

方法 4:基于 OAuth 认证的鉴权

在需要与现有身份验证系统集成时,OAuth 认证是一种常见的选择。通过在连接时使用 OAuth 令牌,服务器可以验证用户的身份。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

const WebSocket = require('ws');

const axios = require('axios');

const server = new WebSocket.Server({ port: 3000 });

server.on('connection', async (socket, req) => {

    const accessToken = req.headers['authorization'];

     

    // 验证OAuth令牌的合法性

    try {

        const response = await axios.get('https://oauth-provider.com/verify', {

            headers: { Authorization: `Bearer ${accessToken}` }

        });

        if (response.data.valid) {

            // 鉴权通过,进行后续操作

            socket.send('鉴权通过,欢迎连接!');

        } else {

            // 鉴权失败,关闭连接

            socket.close();

        }

    } catch (error) {

        // 验证失败,关闭连接

        socket.close();

    }

});

其他常见方法...

除了以上介绍的方式,还有一些其他的鉴权方法,如基于 API 密钥、HTTP 基本认证等。根据具体需求,选择最适合项目的方式。

实践案例

基于 Token 的鉴权实践

  1. 在 WebSocket 连接时,客户端携带 Token 信息。
  2. 服务器接收 Token 信息并验证其合法性。
  3. 根据验证结果,允许或拒绝连接。

1

2

// 客户端代码

const socket = new WebSocket('ws://localhost:3000', ['Bearer YOUR_TOKEN']);

1

2

3

4

5

6

7

8

9

10

// 服务器端代码

server.on('connection', (socket, req) => {

    const token = req.headers['sec-websocket-protocol'];

     

    if (isValidToken(token)) {

        socket.send('鉴权通过,欢迎连接!');

    } else {

        socket.close();

    }

});

基于签名的鉴权实践

  1. 在 WebSocket 连接时,客户端计算签名并携带至服务器。
  2. 服务器接收签名信息,验证其合法性。
  3. 根据验证结果,允许或拒绝连接。

1

2

// 客户端代码

const socket = new WebSocket('ws://localhost:3000', { headers: { 'X-Signature': calculateSignature() } });

1

2

3

4

5

6

7

8

9

10

11

// 服务器端代码

server.on('connection', (socket, req) => {

    const signature = req.headers['x-signature'];

    const data = req.url + req.headers['sec-websocket-key'];

     

    if (isValidSignature(signature, data)) {

        socket.send('鉴权通过,欢迎连接!');

    } else {

        socket.close();

    }

});

基于 IP 白名单的鉴权实践

  1. 在 WebSocket 连接时,服务器获取客户端 IP 地址。
  2. 验证 IP 地址是否在白名单中。
  3. 根据验证结果,允许或拒绝连接。

1

2

3

4

5

6

7

8

9

10

// 服务器端代码

server.on('connection', (socket, req) => {

    const clientIP = req.connection.remoteAddress;

     

    if (allowedIPs.includes(clientIP)) {

        socket.send('鉴权通过,欢迎连接!');

    } else {

        socket.close();

    }

});

基于 OAuth 认证的鉴权实践

  1. 在 WebSocket 连接时,客户端携带 OAuth 令牌。
  2. 服务器调用 OAuth 服务验证令牌的合法性。
  3. 根据验证结果,允许或拒绝连接。

1

2

// 客户端代码

const socket = new WebSocket('ws://localhost:3000', { headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' } });

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

// 服务器端代码

server.on('connection', async (socket, req) => {

    const accessToken = req.headers['authorization'];

     

    try {

        const response = await axios.get('https://oauth-provider.com/verify', {

            headers: { Authorization: `Bearer ${accessToken}` }

        });

        if (response.data.valid) {

            socket.send('鉴权通过,欢迎连接!');

        } else {

            socket.close();

        }

    } catch (error) {

        socket.close();

    }

});

提示、技巧和注意事项

  • 在选择鉴权方式时,要根据项目的实际需求和安全性要求进行合理选择。
  • 对于基于 Token 的鉴权,建议使用 JWT(JSON Web Token)来提高安全性。
  • 在验证失败时,及时关闭连接,以防止未授权的访问。

在 Apifox 中调试 WebSocket

如果你要调试 WebSocket 接口,并确保你的应用程序能够正常工作。这时,一个强大的接口测试工具就会派上用场。

Apifox 是一个比 Postman 更强大的接口测试工具,Apifox = Postman + Swagger + Mock + JMeter。它支持调试 http(s)、WebSocket、Socket、gRPC、Dubbo 等多种协议的接口,这使得它成为了一个非常全面的接口测试工具,所以强烈推荐去下载体验!

首先在 Apifox 中新建一个 HTTP 项目,然后在项目中添加 WebSocket 接口。

alt

alt

接着输入 WebSocket 的服务端 URL,例如:ws://localhost:3000,然后保存并填写接口名称,然后确定即可。

alt

alt

点击“Message 选项”然后写入“你好啊,我是 Apifox”,然后点击发送,你会看到服务端和其它客户端都接收到了信息,非常方便,快去试试吧!

alt

以下用 Node.js 写的 WebSocket 服务端和客户端均收到了消息。

alt

总结

通过本文的介绍,你应该对 WebSocket 鉴权有了更清晰的认识。不同的鉴权方式各有优劣,你可以根据具体情况选择最适合自己项目的方式。在保障通信安全的同时,也能提供更好的用户体验。

参考链接

  • MDN Web Docs - WebSocket
  • JSON Web Tokens
  • OAuth 2.0

学习更多:

  • WebSocket 如何建立连接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/186339.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鼠标拖拽问题,不选中文本不触发单击事件

文章目录 1. 为什么鼠标单击的时候触发了mousemove事件?明明鼠标没有移动2. 鼠标拖拽元素怎么能不触发单击事件?怎么处理鼠标在元素内的相对定位,而不是每次定位到左上角?方式一:拖拽的元素没有注册click监听就不会触发…

Python报错:AttributeError(类属性、实例属性)

Python报错:AttributeError(类属性、实例属性) Python报错:AttributeError 这个错误就是说python找不到对应的对象的属性,百度后才发现竟然是初始化类的时候函数名写错了 __init__应该有2条下划线,如果只有…

北邮22级信通院数电:Verilog-FPGA(11)第十一周实验(2)设计一个24秒倒计时器

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 1.1 counter_24.v 1.2 divid…

【深度学习】CNN中pooling层的作用

1、pooling是在卷积网络(CNN)中一般在卷积层(conv)之后使用的特征提取层,使用pooling技术将卷积层后得到的小邻域内的特征点整合得到新的特征。一方面防止无用参数增加时间复杂度,一方面增加了特征的整合度…

2、用命令行编译Qt程序生成可执行文件exe

一、创建源文件 1、新建一个文件夹&#xff0c;并创建一个txt文件 2、重命名为main.cpp 3、在main.cpp中添加如下代码 #include <QApplication> #include <QDialog> #include <QLabel> int main(int argc, char *argv[]) { QApplication a(argc, argv); QDi…

在Spring Boot中实现单文件,多文件上传

这篇文章算是一篇水文&#xff0c;因为也没啥好讲的&#xff0c;在Spring Boot中&#xff0c;上传文件是我们常常做的&#xff0c;包括我们在实际开发过程中&#xff0c;我们也经常碰到与文件上传有关的功能&#xff0c;这也算是我们常用的一个功能了&#xff0c;毕竟作为开发者…

分布式数据恢复-hbase+hive分布式存储误删除如何恢复数据?

hbasehive分布式存储数据恢复环境&#xff1a; 16台某品牌R730XD服务器节点&#xff0c;每台物理服务器节点上有数台虚拟机&#xff0c;虚拟机上配置的分布式&#xff0c;上层部署hbase数据库hive数据仓库。 hbasehive分布式存储故障&初检&#xff1a; 数据库文件被误删除…

HarmonyOS应用开发实战—登录页面【ArkTS】

文章目录 本页面实战效果预览图一.HarmonyOS应用开发1.1HarmonyOS 详解1.2 ArkTS详解二.HarmonyOS应用开发实战—登录页面【ArkTS】2.1 ArkTS页面源码2.2 代码解析2.3 心得本页面实战效果预览图 一.HarmonyOS应用开发 1.1HarmonyOS 详解 HarmonyOS(鸿蒙操作系统)是华为公司…

【unity实战】基于权重的随机事件(附项目源码)

文章目录 前言开始一、简单的使用二、完善各种事件1. 完善生成金币事件2. 完善生成敌人事件敌人3. 完善生成药水事件 最终效果参考源码完结 前言 随机功能和UnityEvent前面其实我们都已经做过了&#xff0c;但是随机UnityEvent事件要怎么使用呢&#xff1f;这里就来举一个例子…

Vue3+element-plus,打包报错:Cannot read properties of null (reading ‘insertBefore‘)

一、现象&#xff1a;vue3 element-plus项目&#xff0c;本地启动时&#xff0c;页面所有操作都正常&#xff1b;部署到生产环境后&#xff0c;el-dialog、el-drawer弹框报错。 这个弹框报错问题&#xff0c;困扰好几天&#xff0c;查阅资料&#xff0c;可能是如下几个问题。 …

白嫖CTG4.0

大家好&#xff0c;到点了我来给各位大佬献策CTG&#xff0c;不是花钱买不起&#xff0c;而是免费更有性价比&#xff0c;哈哈哈不调侃了我们自此开始正文&#xff0c;咱们主打的就是一个分享是一种态度 当然我更希望大家支持国产对国产有自己的信心&#xff08;文心一言&…

鸿蒙4.0开发笔记之DevEco Studio如何使用低代码开发模板进行开发的详细流程(六)

鸿蒙低代码开发 一、什么是低代码二、如何进行鸿蒙低代码开发1、 创建低代码开发工程&#xff08;方式壹&#xff09;2、已有工程则创建Visual文件&#xff08;方拾贰&#xff09; 三、低代码开发界面介绍四、低代码实现页面跳转五、低代码开发建议 一、什么是低代码 所谓低代码…

数据结构——单链表(Singly Linked List)

1.链表介绍 链表是一种物理储存上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点&#xff08;链表中每一个元素称为结点&#xff09;组成&#xff0c;结点可以在运行时动态生成。 对于上图&#xff0c;每一个结点都是一个结…

C语言—指针和数组

写在前 一个指针变量指向某个普通变量&#xff0c;则指针变量就等于普通变量。 指针变量存放的是地址&#xff0c;普通变量存放的是数据。 int * p; int i5,j; p &i;此程序&#xff0c;*pi5&#xff0c;在所有出现 *p 或 i 的位置&#xff0c;两者都可以互相替换。 通过…

2023年亚太杯数学建模A题水果采摘机器人的图像识别功能(基于yolov5的苹果分割)

注&#xff1a;.题中附录并没有给出苹果的标签集&#xff0c;所以需要我们自己通过前4问得到训练的标签集&#xff0c;采用的是yolov5 7.0 版本&#xff0c;该版本带分割功能 一&#xff1a;关于数据集的制作&#xff1a; clc; close all; clear; %-----这个是生成yolov5 数据…

2、git进阶操作

2、git进阶操作 2.1.1 分支的创建 命令参数含义git branch (git checkout -b)<new_branch> <old_branch>表示创建分支-d <-D>删除分支 –d如果分支没有合并&#xff0c;git会提醒&#xff0c;-D强制删除-a -v查看分支-m重新命名分支commit id从指定的commi…

【数据结构】树与二叉树(廿二):树和森林的遍历——后根遍历(递归算法PostOrder、非递归算法NPO)

文章目录 5.1 树的基本概念5.1.1 树的定义5.1.2 森林的定义5.1.3 树的术语 5.2 二叉树5.3 树5.3.1 树的存储结构1. 理论基础2. 典型实例3. Father链接结构4. 儿子链表链接结构5. 左儿子右兄弟链接结构 5.3.2 获取结点的算法5.3.3 树和森林的遍历1. 先根遍历&#xff08;递归、非…

XG916Ⅱ轮式装载机后驱动桥设计机械设计CAD

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;装载机 获取完整论文报告工程源文件 本次设计内容为XG916Ⅱ装载机后驱动桥设计&#xff0c;大致上分为主传动的设计&#xff0c;差速器的设计&#xff0c;半轴的设计&#xff0c;最终传动的设计四大部分。其中主传动锥齿轮…

【从删库到跑路】MySQL数据库 — E-R图 | 关系模型

&#x1f38a;专栏【MySQL】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f339;简述什么是E-R图⭐核心概念 &#x1f339;E-R图…

MTK联发科MT6762/MT6763/MT6765安卓核心板参数规格比较

MT6762安卓核心板 MTK6762安卓核心板是一款工业级高性能、可运行 android9.0 操作系统的 4G智能模块。 CPU&#xff1a;4xCortex-A53 up to 2.0Ghz/4xCortex-A53 up to 1.5GhzGraphics&#xff1a;IMG GE8320 Up to 650MhzProcess&#xff1a;12nmMemory&#xff1a;1xLP3 9…