Cookie不适用于Apple设备上的WebSocket

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie不适用于Apple设备上的WebSocket相关的知识,希望对你有一定的参考价值。

我一直在WebSocket前阶段设置和检索cookie以识别用户。我认为一切都可以像典型的HTTP交换一样工作。

这在我测试过的所有浏览器上都运行得很完美,但报告开始报告,在iPhone上登录根本不会保留,表示cookie未设置或发送回服务器。

// fret not, safety checks removed for brevity

const (
    sessionKeyCookieName string = "session-key"
    webSocketPath        string = "/ws"
)

func serveWs(w http.ResponseWriter, r *http.Request) {
    var sessionKey [sha1.Size]byte
    var u *user
    for _, cookie := range r.Cookies() {
        if cookie.Name != sessionKeyCookieName {
            continue
        }
        slice, err := base64.StdEncoding.DecodeString(cookie.Value)
        if err != nil {
            continue
        } else {
            copy(sessionKey[:], slice)
        }
    }
    u, _ = getUserBySessionKey(sessionKey)

    // regenerate key. TODO: does that add security?
    rand.Read(sessionKey[:])

    header := make(http.Header)
    header.Add("Set-Cookie", (&http.Cookie{
        Name:     sessionKeyCookieName,
        Value:    base64.StdEncoding.EncodeToString(sessionKey[:]),
        MaxAge:   int(sessionLength.Seconds()),
        HttpOnly: true,
        Domain:   strings.SplitN(r.Host, ":", 2)[0],
    }).String())

    ws, err := upgrader.Upgrade(w, r, header)
    if err != nil {
        if _, ok := err.(websocket.HandshakeError); !ok {
            log.Println(err)
        }
        return
    }

    // do things to `user` so their messages go to where they're needed

    go c.writePump()
    c.readPump()
}

在Firefox网络开发工具上看到的标题

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: eSazcZyZKj2dfa2UWSY+a4wThC8=
Access-Control-Allow-Origin: *
Set-Cookie: session-key=RNStK2z2gAsan7DyNKQ+efjyr7c=; Domain=redacted.org; Max-Age=259200; HttpOnly

我是否跳过允许Safari存储cookie的步骤,或者这是一个问题上游1?

附:我真的想保留这种方法,因为我可以使用仅限HTTP的cookie,这主要是为了确保javascript无法访问它们。


  1. 看起来加里也有similar issues。简而言之,cookie不会通过WebSockets返回。
答案

如果您的Set-Cookie标头在其他浏览器中工作,我的猜测是它是一个上游问题,特别是ios Safari能够阻止cookie。默认情况下,iOS Safari会阻止第三方Cookie。

Can a webpage in mobile Safari check whether Settings > Safari > Accept Cookies 'From visited' or 'Always' is selected?

如果cookie被阻止,您将无法使用它们。如果您需要cookie,请通过在enabled=1等登录页面上设置cookie来检测支持,然后在/ws处理程序中检查它。如果它出现空白并且cookie被阻止,您可以尝试重定向到/please-enable-cookies以要求用户为您的站点启用cookie。

另一种选择是将签名的会话数据存储在本地存储中,并将其包含在Authorization头中的每个请求中。 https://jwt.io/

另一答案

TLDR:这是HttpOnly旗帜。


看来虽然有些浏览器允许Set-Cookie头在WebSocket连接的响应中有HttpOnly标志,但iOS Safari认为这种情况是“非HTTP”并阻止了这种情况。

有趣的是,虽然无法设置HttpOnly cookie,但在连接WebSocket时会在请求标头中发送HttpOnly cookie。这留下了一对选项:

  • 增加风险并省略HttpOnly;
  • 使用另一个普通的HTTP请求设置您的cookie,很可能是一个甚至没有响应主体的请求。

RFC 6265 Storage model中概述的内容相比,我认为iOS Safari的行为不正确

以上是关于Cookie不适用于Apple设备上的WebSocket的主要内容,如果未能解决你的问题,请参考以下文章

Apple Vision – 条码检测不适用于不同颜色的条码

Apple Push Notification 不适用于非开发的临时构建

地理位置不适用于华为设备上的 WebChromeClient

ios通用重定向链接不适用于真实设备,但适用于模拟器

我的应用不适用于 Google Play 上的平板设备

推送通知不适用于 iphone 中的生产证书?