Skip to main content
WebSockets Tutorial
CHAPTER 11 Beginner

WebSocket Authentication Basics

Updated: May 14, 2026
20 min read

# CHAPTER 11

WebSocket Authentication Basics

1. Introduction

WebSockets are open by default. If you host a WebSocket server, anyone who knows the URL can connect to it. For public echo servers or global chat rooms, this is fine. But for a private dashboard, a direct messaging app, or an administrative panel, you must verify the user's identity before allowing them to subscribe to real-time data. In this chapter, we will explore the unique challenges of WebSocket authentication and how to implement token-based security.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Explain why standard HTTP cookie authentication can be tricky with WebSockets.
  • Authenticate a WebSocket connection via the initial handshake URI.
  • Authenticate a connection via a first-message JSON token.
  • Securely reject unauthenticated connections.

3. Beginner-Friendly Explanation

Imagine a VIP nightclub.
  • HTTP Authentication: Every time you want a drink, you have to show the bartender your ID.
  • WebSocket Authentication: You show your ID to the bouncer at the front door (the Handshake). Once you are inside the club, you don't need to show your ID to anyone anymore. The server trusts you for the duration of the connection.
The challenge is figuring out *how* to show that ID to the bouncer when the browser doesn't allow custom HTTP headers during the new WebSocket() creation.

4. Real-World Examples

  • Stock Trading App: The app connects to the WebSocket server. The server verifies the user's JWT (JSON Web Token). Only then does the server start streaming live portfolio data to that specific user.

5. Authentication Strategies

Unlike fetch() or XMLHttpRequest, the browser's WebSocket API does not allow you to pass custom headers (like Authorization: Bearer <token>) during the handshake. Therefore, we have two primary workarounds:

Strategy 1: Query Parameters (The URI method) Pass the token in the URL itself: ws://server.com?token=abc123xyz

Strategy 2: The Ticket/First-Message Method Connect normally, but the server puts you in a "waiting room". You must immediately send a JSON message containing your token. If the token is valid, the server lets you in. If not, the server closes the connection.

6. Strategy 1: Query Parameters Example

This is the easiest method to implement on the frontend.

7. JavaScript Examples (Query Param)

javascript
1234567891011
// Retrieve your auth token from local storage (or wherever you keep it)
const authToken = localStorage.getItem(&#039;user_token&#039;);

// Append it to the WebSocket URL
const socketUrl = `wss://api.example.com/chat?token=${authToken}`;

const socket = new WebSocket(socketUrl);

socket.onopen = function() {
    console.log("Connected and authenticated!");
};

*Note: The server backend reads the $_GET['token'] during the HTTP Upgrade phase and rejects the handshake if the token is invalid.*

8. Strategy 2: First-Message Example

This method is considered slightly more secure because URLs (including query parameters) are sometimes logged in server access logs, which could leak tokens.
javascript
123456789101112131415161718192021222324
const socket = new WebSocket("wss://api.example.com/chat");

socket.onopen = function() {
    // Do NOT allow the user to see the UI yet.
    // Immediately send the authentication payload.
    const authPayload = {
        action: &#039;authenticate&#039;,
        token: localStorage.getItem(&#039;user_token&#039;)
    };
    
    socket.send(JSON.stringify(authPayload));
};

socket.onmessage = function(event) {
    const data = JSON.parse(event.data);
    
    if (data.status === &#039;authenticated&#039;) {
        console.log("Server accepted our token!");
        // NOW show the chat UI
    } else if (data.status === &#039;unauthorized&#039;) {
        console.error("Auth failed.");
        socket.close();
    }
};

9. PHP Backend Concept

When we build our server later, handling Strategy 2 looks like this:
php
1234567891011121314151617181920
<?php
// PHP Server Pseudocode
public function onMessage(ConnectionInterface $conn, $msg) {
    $data = json_decode($msg);
    
    // Check if they are authenticated yet
    if (!isset($conn->isAuthenticated) || $conn->isAuthenticated === false) {
        
        if ($data->action === &#039;authenticate' && validateToken($data->token)) {
            $conn->isAuthenticated = true;
            $conn->send(json_encode([&#039;status' => 'authenticated']));
        } else {
            // Bad token, kick them out
            $conn->close(); 
        }
        return; // Stop processing further
    }
    
    // Normal chat logic goes here...
}

10. Best Practices

  • Use Short-Lived Tokens: If you use the Query Parameter method, don't use the user's permanent session token. Generate a temporary "WebSocket Ticket" via an HTTP API that expires in 60 seconds, and pass *that* in the WebSocket URL.
  • Enforce WSS: Never send authentication tokens over unencrypted ws://. Always use wss:// to protect tokens from man-in-the-middle attacks.

11. Common Mistakes

  • Relying on HTTP Cookies: While WebSockets *do* send browser cookies during the handshake, relying on them is tricky if your WebSocket server is hosted on a different subdomain (e.g., ws.example.com) than your main website, due to strict browser CORS and SameSite cookie policies.

12. Mini Exercises

  1. 1. Look at the URL structure in Strategy 1. If someone looked over your shoulder and copied that URL, could they connect to your chat? *(Answer: Yes, which is why temporary tickets are preferred over permanent tokens).*

13. Coding Challenges

Challenge 1: Modify the JavaScript in Section 8 to include a setTimeout. If the server doesn't respond with status: 'authenticated' within 5 seconds of the connection opening, automatically close the socket from the client side.

14. MCQs with Answers

Question 1

Why can't we use standard HTTP Authorization headers when initializing a WebSocket in JavaScript?

Question 2

What is a risk of passing an authentication token in a WebSocket URL query parameter?

15. Interview Questions

  • Q: Explain the "Ticket" or "First-Message" approach to WebSocket authentication.
  • Q: Why might using standard browser cookies be difficult for authenticating a WebSocket connection on a separate domain?

16. FAQs

Q: Do I have to re-authenticate every time a message is sent? A: No! The beauty of WebSockets is statefulness. Once you validate the user during the handshake or the first message, you mark that Connection object as "Authorized" in the server's memory for the lifetime of that connection.

17. Summary

In Chapter 11, we tackled WebSocket authentication. Because the JavaScript API limits custom headers, developers must pass authentication tokens either through the URI parameters or immediately upon connection via a JSON payload. Verifying users ensures that sensitive real-time data is only broadcast to authorized clients.

18. Next Chapter Recommendation

We have repeatedly mentioned wss:// for encryption, but how do you actually implement it? Proceed to Chapter 12: Secure WebSockets (WSS) to understand SSL/TLS integration and protecting your data in transit.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·