dart-lang / web_socket_channel

StreamChannel wrappers for WebSockets.
https://pub.dev/packages/web_socket_channel
BSD 3-Clause "New" or "Revised" License
423 stars 112 forks source link

Possible issue with headers and authentication #41

Open xbassols opened 5 years ago

xbassols commented 5 years ago

Hello!

I'm not sure is an issue of this library but it could be so here it is what I'm stuck in:

I'm using https://pub.dartlang.org/packages/stomp as a communication protocol but using web_socket_channel as websocket library because theirs have problems in Flutter.

With no authentication everything seems to work fine. The problem appears when I try to set a User header (bear with me here I'm not an expert on websockets) it seems that the websocket client library does not keep sending that header.

Since I might be confusing things, here is an example of the problem. As you can see this is the answer sent from the server to the client in flutter after the connect where I've authenticated the user and set it in the headers.

screenshot 2018-12-18 at 17 51 46

Here you can see the next action (subscribe) sent from the client (flutter) to the server where the client header does not appear again.

screenshot 2018-12-18 at 17 52 00

In order to discard the possibility of a bad configuration on the server side I've tested this with a javascript client and it worked well.

Any suggestions of what could be happening here?

Thanks!

Philip-Wu commented 5 years ago

I'm getting a similar error on a different IP:

SocketException: Failed host lookup: 'http://10.0.2.2:8080/stomp' (OS Error: No address associated with hostname, errno = 7)
E/flutter (29911): #0      _NativeSocket.lookup.<anonymous closure> (dart:io/runtime/binsocket_patch.dart:368:9)
E/flutter (29911): #1      _RootZone.runUnary (dart:async/zone.dart:1379:54)
E/flutter (29911): #2      _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
E/flutter (29911): #3      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:642:45)
tduchateau commented 4 years ago

I was getting a similar issue with authentication. The following did the trick for me with Spring Security and JWT-based authentication.

Update the modified version custom_stomp posted here (thx for that @xbassols!) as follows:

Future<StompClient> connect(String url,
    {String host,
      String login,
      String passcode,
      Map<String, dynamic> headers, // <--- here
      List<int> heartbeat,
      void onConnect(StompClient client, Map<String, String> headers), // <--- here
      void onDisconnect(StompClient client),
      void onError(StompClient client, String message, String detail,
          Map<String, String> headers),
      void onFault(StompClient client, error, stackTrace)}) async =>
    connectWith(await IOWebSocketChannel.connect(url,
        headers: headers), // <--- and here
        host: host,
        login: login,
        passcode: passcode,
        heartbeat: heartbeat,
        onConnect: onConnect,
        onDisconnect: onDisconnect,
        onError: onError,
        onFault: onFault);

Then you can pass authentication headers on connect.

Future<StompClient> clientFuture = customStomp.connect(
        'ws://localhost:8080/ws',
        headers: {'Authorization': 'Bearer $accessToken'},
        onConnect: ...

Then these headers will be intercepted by Spring to perform authentication. Hope it helps!

AndreyDAraya commented 3 weeks ago

Use this:


 import 'package:web_socket_channel/io.dart';

      _channel = IOWebSocketChannel.connect(
        url,
        headers: {
          'Authorization': 'Bearer $apiKey',
        },
      );