从零开始的 WebSocket 鉴权实践指南

liam
• 阅读 403

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

从零开始的 WebSocket 鉴权实践指南

使用场景

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

WebSocket 调试工具

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

从零开始的 WebSocket 鉴权实践指南

常见方法

方法 1:基于 Token 的鉴权

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

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:基于签名的鉴权

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

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 白名单的鉴权方式。

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 令牌,服务器可以验证用户的身份。

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. 根据验证结果,允许或拒绝连接。
// 客户端代码
const socket = new WebSocket('ws://localhost:3000', ['Bearer YOUR_TOKEN']);
// 服务器端代码
server.on('connection', (socket, req) => {
    const token = req.headers['sec-websocket-protocol'];

    if (isValidToken(token)) {
        socket.send('鉴权通过,欢迎连接!');
    } else {
        socket.close();
    }
});

基于签名的鉴权实践

  1. 在 WebSocket 连接时,客户端计算签名并携带至服务器。
  2. 服务器接收签名信息,验证其合法性。
  3. 根据验证结果,允许或拒绝连接。
// 客户端代码
const socket = new WebSocket('ws://localhost:3000', { headers: { 'X-Signature': calculateSignature() } });
// 服务器端代码
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. 根据验证结果,允许或拒绝连接。
// 服务器端代码
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. 根据验证结果,允许或拒绝连接。
// 客户端代码
const socket = new WebSocket('ws://localhost:3000', { headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' } });
// 服务器端代码
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 接口。

从零开始的 WebSocket 鉴权实践指南

从零开始的 WebSocket 鉴权实践指南

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

从零开始的 WebSocket 鉴权实践指南

从零开始的 WebSocket 鉴权实践指南

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

从零开始的 WebSocket 鉴权实践指南

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

从零开始的 WebSocket 鉴权实践指南

总结

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

参考链接

学习更多:

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
TARS的服务鉴权功能|避免数据泄露
!(https://oscimg.oschina.net/oscnet/084208376c754453a44175dc09e16402.gif)在我们使用微服务架构时,经常会选择通过RPC通信框架方便地实现服务间的调用。但方便的同时也带来了一些安全隐患,任何用户都能够访问对外公开的接口,可能造成部分敏感数据的泄露,这是我们不希望
Stella981 Stella981
3年前
B站微服务框架Kratos详细教程(2)
背景在像微服务这样的分布式架构中,经常会有一些需求需要你调用多个服务,但是还需要确保服务的安全性、统一化每次的请求日志或者追踪用户完整的行为等等。你可能需要一个框架来帮助你实现这些功能。比如说帮你在一些关键路径的请求上配置必要的鉴权或超时策略。那样服务间的调用会被多层中间件所过滤并检查,确保整体服务的稳定性。设计目标
Stella981 Stella981
3年前
SpringBoot项目中使用AOP
1.概述将通用的逻辑用AOP技术实现可以极大的简化程序的编写,例如验签、鉴权等。Spring的声明式事务也是通过AOP技术实现的。具体的代码参照示例项目https://github.com/qihaiyan/springcamp/tree/master/springaop(https://www.oschina.net/actio
Easter79 Easter79
3年前
SpringBoot项目中使用AOP
1.概述将通用的逻辑用AOP技术实现可以极大的简化程序的编写,例如验签、鉴权等。Spring的声明式事务也是通过AOP技术实现的。具体的代码参照示例项目https://github.com/qihaiyan/springcamp/tree/master/springaop(https://www.oschina.net/actio
Wesley13 Wesley13
3年前
RTSP拉流协议视频平台多点认证造成潜在威胁?如何破解?
上一篇我们讲了TSINGSEE青犀视频平台EasyNVR内登陆鉴权的优化,通过优化登陆鉴权,我们可以抵御很多分发用户的攻击。在该问题优化完成后,我们模拟不法分子的攻击对EasyNVR的安全性进行了测试,EasyNVR已经达到了一个安全性很高的级别。!203.png(https://imgblog.csdnimg.cn/img_convert/937
Stella981 Stella981
3年前
Spring Cloud微服务架构从入门到会用(五)—服务网关鉴权
上一篇文章我们集成了服务网关SpringCloudGateway,所有的服务请求都可以通过Gateway访问。那我们就可在服务网关这一层对用户的请求进行鉴权,判断是否可以访问路由的API接口。接下来我们开始增加鉴权,这里我们使用jwt1\.创建授权服务module按照第二篇文章创建一个module,起名为appauth。
Stella981 Stella981
3年前
CDN a,b,c三种鉴权的PHP代码
A鉴权方式的代码//http://DomainName/Filename?auth\_keytimestampranduidmd5hash//sstring"URITimestampranduidPrivateKey"(URI是用户的请求对象相对地址,如/Filename)//HashValuemd5su
Stella981 Stella981
3年前
SpringBoot之actuator
在springBoot中集成actuator可以很方便的管理和监控应用的状态。暴露的Restful接口有:HTTP方法路径描述鉴权GET/autoconfig查看自动配置的使用情况trueGET/configprops查看配置属性,包括默认配置trueGET/beans查看bean及其关系列表
Easter79 Easter79
3年前
SpringBoot之actuator
在springBoot中集成actuator可以很方便的管理和监控应用的状态。暴露的Restful接口有:HTTP方法路径描述鉴权GET/autoconfig查看自动配置的使用情况trueGET/configprops查看配置属性,包括默认配置trueGET/beans查看bean及其关系列表
你想要的【微前端】都在这里了! | 京东云技术团队
某次遇到一个从0到1的大型项目,该项目涉及两个端,除了鉴权和部分业务逻辑不同外,页面UI和其余逻辑几乎一致,遇到这种项目,该如何架构?既能保证项目顺利开发完成,又能保证后期的迭代、维护、可扩展?