Secure WebSocket Traffic
WebSocket provides persistent, bidirectional communication over a single TCP connection. After the initial connection is established, the client and server can exchange messages without creating a new HTTP request for every interaction. This makes WebSocket suitable for live feeds, chat, collaborative applications, multiplayer games, and other workloads that require low-latency updates.
Each WebSocket connection begins as an HTTP upgrade request. The gateway must make its authentication decision during this handshake, before the connection becomes a long-lived communication channel. APISIX can apply an authentication plugin to the upgrade request and reject unauthorized clients before allowing the protocol switch.
This guide configures the key-auth plugin and uses websocat, a command-line client that can add a credential header to the handshake, to verify both rejected and authenticated connections. Browser WebSocket APIs do not allow applications to set arbitrary request headers, so browser applications should use an authentication method and credential transport that fit their client architecture. The same handshake can use another APISIX authentication plugin when it better matches the client and application.
Prerequisite(s)
- Install Docker.
- Install cURL to configure APISIX through the Admin API.
- Install websocat to establish WebSocket connections.
- Follow the Getting Started tutorial to start an APISIX instance in Docker.
Start a WebSocket Upstream
Set GATEWAY_CONTAINER to the running APISIX container. Create a dedicated network and connect the gateway to it:
export GATEWAY_CONTAINER=replace-with-apisix-container-name
docker network create gateway-websocket-net
docker network connect gateway-websocket-net "$GATEWAY_CONTAINER"Start a pinned sample WebSocket server on the shared network:
docker run -d \
--name websocket-server \
--network gateway-websocket-net \
jmalloc/echo-server:v0.3.7The server exposes /.ws, which echoes each received message.
Create a Route
Create a route that enables WebSocket proxying and requires key-auth credentials:
curl "http://127.0.0.1:9180/apisix/admin/routes/websocket-auth" -X PUT \
-d '{
"uri": "/.ws",
"enable_websocket": true,
"plugins": {
"key-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"websocket-server:8080": 1
}
}
}'services:
- name: websocket-auth
labels:
docs-example: secure-websocket-traffic
routes:
- name: websocket-auth
uris:
- /.ws
enable_websocket: true
plugins:
key-auth: {}
upstream:
type: roundrobin
nodes:
- host: websocket-server
port: 8080
weight: 1Create a Consumer
Create a consumer named john with a key-auth credential:
Create the consumer:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-d '{
"username": "john"
}'Create the credential:
curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
-d '{
"id": "john-key-auth",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'consumers:
- username: john
labels:
docs-example: secure-websocket-traffic
credentials:
- name: john-key-auth
type: key-auth
config:
key: john-keyADC reconciles services and consumers as desired state. Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:
adc diff -f route.yaml -f consumer.yaml \
--include-resource-type service \
--include-resource-type consumer \
--label-selector docs-example=secure-websocket-trafficSynchronize the reviewed service and consumer configurations:
adc sync -f route.yaml -f consumer.yaml \
--include-resource-type service \
--include-resource-type consumer \
--label-selector docs-example=secure-websocket-trafficVerify Authentication
Open the route without credentials:
websocat "ws://127.0.0.1:9080/.ws"APISIX should reject the handshake with 401 Unauthorized.
Open the route with John's credential:
websocat "ws://127.0.0.1:9080/.ws" -H "apikey: john-key"Send hello. The server should echo the message:
Request served by <container-id>
hello
helloThe successful upgrade and echoed message confirm that APISIX authenticated the handshake and proxies traffic in both directions.
Next Steps
You have configured APISIX to authenticate WebSocket upgrade requests. To control the number of concurrent connections, see Rate Limit WebSocket Connections.