概述
WebSocket作為一種通信協議引入到Web應用中,并不會解決Web應用中存在的安全問題,因此WebSocket應用的安全實現是由開發者或服務端負責。這就要求開發者了解WebSocket應用潛在的安全風險,以及如何做到安全開發規避這些安全問題。
認證
使用JWT進行身份認證是一種常見的做法,因為它可以方便地在客戶端和服務器之間傳遞用戶的身份信息。在WebSocket通信中,可以通過URL地址傳遞令牌參數來實現JWT身份認證。
服務端
GatewayWorker
GatewayWorker是基于Workerman開發的一個可分布式部署的TCP長連接框架,專門用于快速開發TCP長連接應用,例如app推送服務端、即時IM服務端、游戲服務端、物聯網、智能家居等等.
安裝地址:https://www.workerman.net/doc/gateway-worker
生成令
安裝jwt插件
composer require tinywan/php-jwt
生成一個訪問令牌
<?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);
執行輸出
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VyX2lkIjoyMDUwMTAwMDAwMSwidXNlcm5hbWUiOiJUaW55d2FuIiwiZXhwIjoxNzQ5OTk5NTU1fQ.
om7PERuIAzEfPoEui1wJd40M4QJ-CE5gMisiG7Gc0NY
服務端認證 ??
WebSocket 接入連接后,服務端將解析 URL 參數中的Authorization
令牌.
// 當客戶端連接上來時,設置連接的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 參數中。
連接地址格式如下:
ws://后端IP:端口/?Authorization=Bearer eyJ0eXAi...
調試案例
var ws = new WebSocket('ws://127.0.0.1:8782/?Authorization={{token}}');
ws.onmessage = function(event) {
console.log('開源技術小棧接收消息: ' + event.data);
};
如果服務端支持請求頭認證,也可使用如下形式傳參:
headers:{
Authorization:"Bearer "+getToken(),
}
令牌認證
var ws = new WebSocket('ws://127.0.0.1:8782/?Authorization={{token}}');
ws.onmessage = function(event) {
console.log('開源技術小棧接收消息: ' + event.data);
};
客戶端連接截圖
服務端認證結果
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)
}
參考
?
閱讀原文:https://mp.weixin.qq.com/s/OOVBmJt2BQYckerTn15gbg
該文章在 2025/6/17 18:14:37 編輯過