Sepertinya mudah untuk menambahkan header HTTP khusus ke klien websocket Anda dengan klien header HTTP apa pun yang mendukung ini, tapi saya tidak dapat menemukan cara melakukannya dengan API JSON.
Namun, tampaknya harus ada dukungan header ini di spec .
Adakah yang tahu cara mencapainya?
var ws = new WebSocket("ws://example.com/service");
Khususnya, saya harus dapat mengirim tajuk Otorisasi HTTP.
javascript
http
header
websocket
Julien Genestoux
sumber
sumber
connect
permintaan awal . Saya menggunakan saluran Django di bagian belakang dan saya telah merancang itu untuk menerima koneksi padaconnect
acara. itu kemudian menetapkan bendera "is_auth" dalamreceive
acara tersebut (jika ia melihat pesan auth valid). jika flag is_auth tidak diset dan itu bukan pesan auth maka itu menutup koneksi.Jawaban:
Dimutakhirkan 2x
Jawaban singkat: Tidak, hanya bidang jalur dan protokol yang dapat ditentukan.
Jawaban yang lebih panjang:
Tidak ada metode dalam JavaScript WebSockets API untuk menentukan header tambahan untuk dikirim oleh klien / browser. Jalur HTTP ("GET / xyz") dan header protokol ("Sec-WebSocket-Protocol") dapat ditentukan dalam konstruktor WebSocket.
Header Sec-WebSocket-Protocol (yang terkadang diperluas untuk digunakan dalam otentikasi spesifik websocket) dihasilkan dari argumen kedua opsional ke konstruktor WebSocket:
Hasil di atas dalam tajuk berikut:
dan
Pola umum untuk mencapai otentikasi / otorisasi WebSocket adalah menerapkan sistem tiket di mana halaman yang menampung klien WebSocket meminta tiket dari server dan kemudian melewati tiket ini selama pengaturan koneksi WebSocket baik dalam URL / kueri string, di bidang protokol, atau diperlukan sebagai pesan pertama setelah koneksi dibuat. Server kemudian hanya memungkinkan koneksi untuk melanjutkan jika tiket valid (ada, belum pernah digunakan, IP klien disandikan dalam pertandingan tiket, timestamp dalam tiket baru-baru ini, dll). Berikut ini ringkasan informasi keamanan WebSocket: https://devcenter.heroku.com/articles/websocket-security
Otentikasi dasar sebelumnya merupakan opsi tetapi ini sudah usang dan browser modern tidak mengirim header bahkan jika itu ditentukan.
Info Auth Dasar (Usang) :
Header Otorisasi dihasilkan dari bidang nama pengguna dan kata sandi (atau hanya nama pengguna) dari WebSocket URI:
Hasil di atas dalam tajuk berikut dengan string "nama pengguna: kata sandi" base64 disandikan:
Saya telah menguji otentikasi dasar di Chrome 55 dan Firefox 50 dan memverifikasi bahwa info otentikasi dasar memang dinegosiasikan dengan server (ini mungkin tidak berfungsi di Safari).
Terima kasih kepada Dmitry Frank atas jawaban auth dasar
sumber
Lebih dari solusi alternatif, tetapi semua browser modern mengirim cookie domain beserta koneksi, jadi gunakan:
Berakhir dengan tajuk koneksi permintaan:
sumber
Masalah header Otorisasi HTTP dapat diatasi dengan hal berikut:
Kemudian, header HTTP Otorisasi Dasar yang tepat akan ditetapkan dengan yang disediakan
username
danpassword
. Jika Anda membutuhkan Otorisasi Dasar, maka Anda siap.Namun saya ingin menggunakan
Bearer
, dan saya menggunakan trik berikut: Saya terhubung ke server sebagai berikut:Dan ketika kode saya di sisi server menerima tajuk Otorisasi Dasar dengan nama pengguna tidak kosong dan kata sandi kosong, maka kode itu menafsirkan nama pengguna sebagai token.
sumber
wss://user:[email protected]/ws
) Dan tidak mendapatkanAuthorization
header di sisi server (menggunakan Chrome versi 60)wss://user:pass@host
format. Apakah ini tidak didukung oleh browser, atau ada yang tidak beres dengan jabat tangan?Anda tidak dapat menambahkan tajuk tetapi, jika Anda hanya perlu memberikan nilai ke server pada saat koneksi, Anda dapat menentukan bagian string kueri di url:
URL itu valid tetapi - tentu saja - Anda harus mengubah kode server Anda untuk menguraikannya.
sumber
Anda tidak dapat mengirim tajuk khusus saat Anda ingin membuat koneksi WebSockets menggunakan JavaScript WebSockets API. Anda bisa menggunakan
Subprotocols
header dengan menggunakan konstruktor kelas WebSocket kedua:dan kemudian Anda bisa mendapatkan header Subprotocols menggunakan
Sec-WebSocket-Protocol
kunci di server.Ada juga batasan, nilai header Subprotocols Anda tidak boleh mengandung koma (
,
)!sumber
Sec-WebSocket-Protocol
header sebagai penggantiAuthorization
header?Mengirim header Otorisasi tidak dimungkinkan.
Melampirkan parameter permintaan token adalah opsi. Namun, dalam beberapa keadaan, mungkin tidak diinginkan untuk mengirim token login utama Anda dalam teks biasa sebagai parameter kueri karena itu lebih buram daripada menggunakan header dan akhirnya akan dicatat di mana saja. Jika ini menimbulkan masalah keamanan bagi Anda, alternatifnya adalah menggunakan token JWT sekunder hanya untuk hal-hal soket web .
Buat titik akhir REST untuk menghasilkan JWT ini , yang tentu saja hanya dapat diakses oleh pengguna yang diautentikasi dengan token login utama Anda (dikirim melalui header). JWT soket web dapat dikonfigurasi secara berbeda dari token masuk Anda, mis. Dengan batas waktu lebih pendek, jadi lebih aman untuk mengirim sekitar sebagai parameter permintaan permintaan upgrade Anda.
Buat JwtAuthHandler terpisah untuk rute yang sama dengan Anda mendaftarkan eventbusHandler SockJS . Pastikan auth handler Anda terdaftar terlebih dahulu, sehingga Anda dapat memeriksa token soket web terhadap database Anda (JWT entah bagaimana harus ditautkan ke pengguna Anda di backend).
sumber
Benar-benar meretasnya seperti ini, berkat jawaban kanaka.
Klien:
Server (menggunakan Koa2 dalam contoh ini, tetapi harus serupa di mana saja):
sumber
Kasus saya:
www.mycompany.com/api/ws
...localhost:8000
).Pengaturan
document.cookie = "sessionid=foobar;path=/"
tidak akan membantu karena domain tidak cocok.Solusinya :
Tambahkan
127.0.0.1 wsdev.company.com
ke/etc/hosts
.Dengan cara ini browser Anda akan menggunakan cookie dari
mycompany.com
saat terhubung kewww.mycompany.com/api/ws
saat Anda terhubung dari subdomain yang validwsdev.company.com
.sumber
Dalam situasi saya (Wawasan Seri Waktu Azure wss: //)
Menggunakan bungkus ReconnectingWebsocket dan dapat mencapai penambahan header dengan solusi sederhana:
Di mana payload dalam hal ini adalah:
sumber
Secara teknis, Anda akan mengirim header ini melalui fungsi sambung sebelum fase peningkatan protokol. Ini berhasil bagi saya dalam sebuah
nodejs
proyek:sumber
headers
Harus berupa null atau objek yang menentukan header permintaan HTTP tambahan sewenang-wenang untuk dikirimkan bersama dengan permintaan." dari WebSocketClient.md ; oleh karena itu, diheaders
sini adalah lapisan HTTP.connect
metode ini, yang dijelaskan sebagaiconnect(requestUrl, requestedProtocols, [[[origin], headers], requestOptions])
, yaituheaders
harus disediakan bersama denganrequestOptions
, misalnyaws.connect(url, '', headers, null)
,. Hanyaorigin
string yang dapat diabaikan dalam kasus ini.Anda bisa melewatkan header sebagai nilai kunci di parameter ketiga (opsi) di dalam objek. Contoh dengan token Otorisasi. Meninggalkan protokol (parameter kedua) sebagai nol
Sunting: Tampaknya pendekatan ini hanya berfungsi dengan perpustakaan nodejs bukan dengan implementasi browser standar. Meninggalkannya karena mungkin bermanfaat bagi sebagian orang.
sumber