You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Postman如何在WebSocket请求中发送自定义头部?附我的OAuth实现场景

WebSocket OAuth认证:Postman自定义头部实现原理及可行替代方案

为什么浏览器原生WebSocket没法加自定义头部

标准浏览器原生WebSocket API(new WebSocket())在握手阶段确实不支持自定义HTTP头部——这是因为浏览器严格遵循RFC 6455规范,只允许传递少数预定义的握手头部(比如Sec-WebSocket-Key、Sec-WebSocket-Version),自定义头部会被浏览器直接拦截或忽略。

Postman是怎么实现WebSocket自定义头部的

Postman根本没用到浏览器原生的WebSocket API,它是用独立的HTTP客户端逻辑完成握手的:

  • 发起WebSocket连接前,Postman会手动构造完整的HTTP握手请求,在这个请求里可以随便加自定义头部(包括Authorization: Bearer <token>)。
  • 握手成功后,再切换到WebSocket协议进行数据传输。
  • 这种方式绕开了浏览器的限制,因为它不受浏览器安全策略和标准API的约束,相当于自己实现了一套WebSocket客户端。

针对你场景的OAuth认证替代方案

既然浏览器原生API走不通,给你几个实际能用的方案:

1. 在WebSocket URL里带Token

把Bearer Token作为URL参数传递,示例:

// 前端代码
const token = '你的OAuth令牌';
const ws = new WebSocket(`wss://你的服务器地址/ws?token=${token}`);

Go后端解析参数验证:

// Go后端示例(基于gorilla/websocket)
func serveWs(w http.ResponseWriter, r *http.Request) {
    token := r.URL.Query().Get("token")
    // 验证令牌有效性,比如解析JWT
    if !validateToken(token) {
        http.Error(w, "Unauthorized", http.StatusUnauthorized)
        return
    }
    // 后续WebSocket握手逻辑
    conn, err := upgrader.Upgrade(w, r, nil)
    // ...
}

注意:一定要用wss(WebSocket over TLS),避免令牌在传输过程中泄露,同时URL参数可能会出现在服务器日志里,敏感场景要考虑这点。

2. 先拿临时凭证再连WebSocket

  • 前端先调用一个HTTP接口(比如POST /auth/websocket),带上Bearer Token完成身份验证,后端返回一个短期有效的临时凭证。
  • 前端用这个临时凭证,要么作为URL参数,要么放在Sec-WebSocket-Protocol头部(这个是标准允许的自定义标识字段)发起WebSocket连接。
  • 后端验证临时凭证有效后,再建立连接。

示例代码:
前端获取临时凭证:

async function getWsTempToken() {
    const resp = await fetch('/auth/websocket', {
        method: 'POST',
        headers: {
            'Authorization': 'Bearer 你的OAuth令牌'
        }
    });
    const data = await resp.json();
    return data.tempToken;
}

// 发起WebSocket连接
const tempToken = await getWsTempToken();
const ws = new WebSocket('wss://你的服务器地址/ws', [tempToken]);

Go后端解析Sec-WebSocket-Protocol:

func serveWs(w http.ResponseWriter, r *http.Request) {
    tempToken := r.Header.Get("Sec-WebSocket-Protocol")
    if !validateTempToken(tempToken) {
        http.Error(w, "Unauthorized", http.StatusUnauthorized)
        return
    }
    // 升级连接时要返回相同的协议头,符合规范
    upgrader.Subprotocols = []string{tempToken}
    conn, err := upgrader.Upgrade(w, r, nil)
    // ...
}

3. 用Cookie传递Token

如果你的前后端是同域的,可以把OAuth Token存在HttpOnly、Secure属性的Cookie里——WebSocket握手本质是HTTP请求,浏览器会自动携带同域Cookie。
Go后端从Cookie取Token验证:

func serveWs(w http.ResponseWriter, r *http.Request) {
    cookie, err := r.Cookie("auth_token")
    if err != nil || !validateToken(cookie.Value) {
        http.Error(w, "Unauthorized", http.StatusUnauthorized)
        return
    }
    // ...
}

跨域场景要配置好CORS和Cookie的SameSite属性,确保Cookie能被正确携带。

内容的提问来源于stack exchange,提问作者longvanren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:12:03