This line, seems to detect if we are in a node.js environment:
However, I am trying to set in the browser (Angular) :
extraHeaders : { Authorization : 'Bearer xxxx' }
for JWT authentication to my REST service, hapi-io, which supports token authentication for websockets.
How else can I set a header or accomplish the same thing?
If I comment code around 2177, it doesn't not send the header.
Thanks
Note for people who found this via google in the future:
As a work around for now, I am passing the token in the query ( io.connect(undefined, { query : "token="+auth.getToken()} );
Then, on my server which is Hapi, I use hapi-auth-jwt2 which has a authentication strategy for tokens that has query parameter /?token=
However I would like to use extraHeaders if possible. Thanks!
Thanks @fullstackwebdev. I'm having trouble to find the documentation of the options.
@fullstackwebdev I've been fighting with extraHeaders in an angular app all day. I too think extraHeaders during the initial handshake would be the best way.
I just successfully implemented this concept which seems like a more elegant solution than passing query parameters. I think it should be safe if you are using SSL/wss.
Basically, you let the socket connect, but then make the client pass their token in an 'authorize' message.
Something like this (server):
io.on('connection', function (socket) {
socket.authorized = false;
socket.emit('connected', {connected: true, authorized: false});
setTimeout(function(){
if(!socket.authorized) {
socket.disconnect(true);
}, 1000; //1 second to authorize or kill the socket
socket.on('authorize', function(data) {
//validate token, set socket.authorized = true, socket.username etc
and this (client):
var socket = io(host);
socket.on('connected' function (data) {
console.log("connected but not authorized");
socket.emit('authorize', {token: "oauth/JWT token goes here";
});
socket.on('authorized', function (data) {
console.log("authorized");
});
They have a point. If I remember correctly since sending headers is not the in the official spec of Websocket is not something they want to support.
The way I fixed this in my case is by sending the value I want to send through a cookie. But query params works too.
So this is supported now?
So it seems like this was added to master. Does anyone know if other clients (android,ios) will implement this soon ?
@vitriol @gaastonsr this is related to https://github.com/socketio/engine.io-client/issues/554
@fullstackwebdev since 2.0.0
, you can now provide an extraHeaders
object:
const socket = io({
transportOptions: {
polling: {
extraHeaders: {
'x-clientid': 'abc'
}
}
}
});
Added to the documentation here.
This issue should be reopened for the websocket
transport.
In the socket.io
API documentation you've placed a link to the WebSocket RFC, chapter 4, but if you keep reading in there you'll encounter this paragraph:
12. The request MAY include any other header fields, for example,
cookies [RFC6265] and/or authentication-related header fields
such as the |Authorization| header field [RFC2616], which are
processed according to documents that define them.
So, there's no rule against setting other headers from the browser, when establishing WebSocket connections - quite the contrary. By coincidence or not, I landed here precisely because of an authentication problem.
The engine.io-client's documentation should be ammended, too.
I got it, you're missing a proper API in browser. Damn.
Most helpful comment
@fullstackwebdev since
2.0.0
, you can now provide anextraHeaders
object:Added to the documentation here.