首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WebSocket 实时通信 JWT 安全认证实现

WebSocket 实时通信 JWT 安全认证实现

作者头像
Tinywan
发布2025-06-16 12:14:04
发布2025-06-16 12:14:04
28300
代码可运行
举报
文章被收录于专栏:开源技术小栈开源技术小栈
运行总次数:0
代码可运行

概述

WebSocket作为一种通信协议引入到Web应用中,并不会解决Web应用中存在的安全问题,因此WebSocket应用的安全实现是由开发者或服务端负责。这就要求开发者了解WebSocket应用潜在的安全风险,以及如何做到安全开发规避这些安全问题。

认证

使用JWT进行身份认证是一种常见的做法,因为它可以方便地在客户端和服务器之间传递用户的身份信息。在WebSocket通信中,可以通过URL地址传递令牌参数来实现JWT身份认证。

服务端

GatewayWorker

GatewayWorker是基于Workerman开发的一个可分布式部署的TCP长连接框架,专门用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等.

安装地址:https://www.workerman.net/doc/gateway-worker

生成令

安装jwt插件

代码语言:javascript
代码运行次数:0
运行
复制
composer require tinywan/php-jwt

生成一个访问令牌

代码语言:javascript
代码运行次数:0
运行
复制
<?php
/**
 * @desc JWT 
 * @author Tinywan(ShaoBo Wan)
 */
declare(strict_types=1);

require'vendor/autoload.php';

// Your secret key (keep this secure)
$secretKey = 'Tinywan2050040000011';

// Create an instance of Jwt
$jwt = new \Tinywan\Jwt($secretKey);

// Create a JWT
$payload = [
    "user_id" => 20501000001,
    "username" => 'Tinywan',
    "exp" => time() + 3600, // Token expiration time (1 hour)
];
$token = $jwt->createToken($payload);

var_dump($token);

执行输出

代码语言:javascript
代码运行次数:0
运行
复制
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VyX2lkIjoyMDUwMTAwMDAwMSwidXNlcm5hbWUiOiJUaW55d2FuIiwiZXhwIjoxNzQ5OTk5NTU1fQ.
om7PERuIAzEfPoEui1wJd40M4QJ-CE5gMisiG7Gc0NY

服务端认证 🔐

WebSocket 接入连接后,服务端将解析 URL 参数中的Authorization令牌.

代码语言:javascript
代码运行次数:0
运行
复制
// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
$gateway->onConnect = function ($connection) {
    $connection->onWebSocketConnect = function ($connection, $http_header) 
    {
       // Your secret key (keep this secure)
        $secretKey = 'Tinywan2050040000011';

        // Create an instance of Jwt
        $jwt = new \Tinywan\Jwt($secretKey);

        // 获取URL参数中的Authorization
        $token = $_GET['Authorization'];

        // Validate and decode the JWT
        if ($jwt->validateToken($token)) {
            echo'JWT is valid.' . PHP_EOL;
            $decodedPayload = $jwt->decodeToken($token);
            echo"Decoded Payload: " . json_encode($decodedPayload, JSON_PRETTY_PRINT) . PHP_EOL;
            var_dump(json_decode(json_encode($decodedPayload), true));
        } else {
            echo'JWT is invalid.' . PHP_EOL;
            return $connection->close();
        }
        returntrue;
    };
};

客户端

在WebSocket通信中加入Token主要是为了实现身份验证和授权,确保只有经过验证的用户可以建立WebSocket连接。由于WebSocket API本身不支持直接在连接时设置HTTP头部,因此需要采用一些变通的方法来传递Token。这里将认证令牌参数Authorization放入 URL 参数中。

连接地址格式如下:

代码语言:javascript
代码运行次数:0
运行
复制
ws://后端IP:端口/?Authorization=Bearer eyJ0eXAi...

调试案例

代码语言:javascript
代码运行次数:0
运行
复制
var ws = new WebSocket('ws://127.0.0.1:8782/?Authorization={{token}}'); 
ws.onmessage = function(event) {
    console.log('开源技术小栈接收消息: ' + event.data);
};

如果服务端支持请求头认证,也可使用如下形式传参:

代码语言:javascript
代码运行次数:0
运行
复制
headers:{
   Authorization:"Bearer "+getToken(),
}

令牌认证

代码语言:javascript
代码运行次数:0
运行
复制
var ws = new WebSocket('ws://127.0.0.1:8782/?Authorization={{token}}'); 
ws.onmessage = function(event) {
    console.log('开源技术小栈接收消息: ' + event.data);
};

客户端连接截图

服务端认证结果

代码语言:javascript
代码运行次数:0
运行
复制
JWT is valid.
Decoded Payload: {
    "user_id": 20501000001,
    "username": "Tinywan",
    "exp": 1749999555
}
/var/www/webman/GatewayWorker/Applications/YourApp/start_gateway.php:49:
array(3) {
'user_id' =>
  int(20501000001)
'username' =>
string(7) "Tinywan"
'exp' =>
  int(1749999555)
}

参考

  1. PHP如何创建和管理JWT令牌
  2. PHP分布式TCP长连接框架 GatewayWorker
  3. WebSocket教程:JWT身份验证参数方式有哪些?
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 认证
  • 服务端
    • GatewayWorker
    • 生成令
    • 服务端认证 🔐
  • 客户端
    • 令牌认证
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档