2017-12-10 10 views
4

WebSocket前の段階でCookieを設定して検索して、ユーザーを特定しています。私は、すべてが典型的なHTTP交換と同様に動作すると仮定しました。AppleデバイスのWebSocketでクッキーが動作しない

これは私がテストしたすべてのブラウザで問題なく動作しましたが、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() 
} 

ヘッダ

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はクッキーを保存することができ、またはこれが問題上流 あるでしょういくつかのステップをスキップアムFirefoxのネットワークのdevのツールに見られるように?

P.S.私はHTTPのみのクッキーを使うことができ、ほとんどの場合、JavaScriptがそれらにアクセスできないことを保証するので、このアプローチを維持したいと思います。


  1. ゲイリーは同様similar issuesを持っているように見えます。簡単に言えば、クッキーはWebSocket上を移動しません。
+1

安全でないクッキーと安全なクッキーはSafariに別々に保存され、セキュアなクッキーが非セキュアな接続にさらされるのを防ぎます。 'http'関連のクッキーから' wss'を使用しようとするか、 'ws'接続に' https'関連のクッキーを使用しようとすると、失敗することになります。 TLSと非TLS接続を混在させることができますか? – Myst

+0

@Myst、私は今は暗号化を使用していません。 – transistor09

+0

ターゲットホスト名は特別な意味を持ちますか(「localhost」、または非TLDなど)?一部のブラウザ/クライアントでは、クッキーを含めるなど、いくつかの特殊な処理があります(たとえば、ドメインプロパティが "localhost"の場合、IEにはCookieが含まれません)。他のホスト名をテストしましたか?ちょうど推測:) –

答えて

2

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?

クッキーがブロックされている場合は、それらを使用することはできません。クッキーが必要な場合は、ログインページでクッキーをenabled=1のように設定してサポートを検出し、/wsハンドラで確認してください。空白になってクッキーがブロックされている場合は、/please-enable-cookiesにリダイレクトして、サイトのCookieを有効にするようユーザーに依頼してください。

もう1つの方法は、署名されたセッションデータをローカルストレージに格納し、それをAuthorizationヘッダーの各要求に含めることです。 https://jwt.io/

関連する問題