stevenroose / dart-eventsource

A client and server implementation of Server-Side Events.
MIT License
56 stars 49 forks source link

Can't authenticate request #16

Open VittorioParagallo opened 3 years ago

VittorioParagallo commented 3 years ago

Is it possible to add the possibility to add authorization header? without it becomes useless in a secured environment :( i've been looking all around last two days and it looks like this feature is missing in the original eventsource api, but there are some implementations with polyfill

jonasbark commented 3 years ago

What makes you think that it's not supported? The connect method accepts a header argument: https://github.com/stevenroose/dart-eventsource/blob/master/lib/eventsource.dart#L61

Though I'm not sure how well / if it works on the Web.

VittorioParagallo commented 3 years ago

Oh.. It has passed a bit of time, i don t really Remember what the point was. I m developing an app for both mobile and web. I ended up using Dio for mobile and wrote a js wrapper around polyfill to solve It. But it would be nice to use only 1 external library like eventsource. As i ll have some free time in november i ll test again eventsource package to see what was the situation with the features. (As i Remember It didn t work on web)

Il ven 9 ott 2020, 13:36 jonasbark notifications@github.com ha scritto:

What makes you think that it's not supported? The connect method accepts a header argument:

https://github.com/stevenroose/dart-eventsource/blob/master/lib/eventsource.dart#L61

Though I'm not sure how well / if it works on the Web.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/stevenroose/dart-eventsource/issues/16#issuecomment-706129870, or unsubscribe https://github.com/notifications/unsubscribe-auth/AN3UJSDIVGIWU4TXY5WGWDLSJ3YSZANCNFSM4QKWDENA .

--

Indirizzo istituzionale di posta elettronica degli studenti e dei laureati dell'Università degli Studi di TorinoOfficial  University of Turin email address for students and graduates 

tnovoselec commented 2 years ago

@VittorioParagallo Could you share your solution for Web? Having the same issue with Web implementation

alexbvw commented 2 years ago

@VittorioParagallo can you please share how you managed to use Dio for SSE with authorization headers? - I am trying the same and it connects but doesn't stream the data

VittorioParagallo commented 1 year ago

I uploaded the code in my repo.

I guess that taking my code and following these steps can you easily to the solution. (my repo is a fully working app)

At first add this js file to the web folder of your flutter project(it's the polyfill): https://github.com/VittorioParagallo/swingcriminals_secretary/blob/master/web/eventsource.js It's the javascript code that does the work done.

Then we need to call that javascript object from dart. so i wrote all the needed code in the folder http_sse_tool

You can download the whole folder, it contains 5 files:

Now that everything is set, is possible to develop the api, the one i did is rest_api_service.dart. In that file you can see the import:

`import 'package:swingcriminals_secretary/http_sse_tool/eventsource_stub.dart'
    // ignore: uri_does_not_exist
       if (dart.library.html) 'package:swingcriminals_secretary/http_sse_tool/eventsource_html.dart'
    // ignore: uri_does_not_exist
       if (dart.library.io) 'package:swingcriminals_secretary/http_sse_tool/eventsource_io.dart';`

So the import dinamically loads the right file wether is a web app or not. That's why a stub with all unimplemented closures was needed.

In the same file you can see the normal get (baseUrl is the webserver and url is the right part endpoint):

`

 Future<dynamic> get(String url) async {
 print("Called RestApiService:get($url)");
var responseJson;
try {
        final response = await http.get(baseUrl + url,
        headers: await AuthService().getRestHeaderWithToken());
        responseJson = _returnResponse(response);
     } on SocketException {
     throw FetchDataException('No Internet connection');
     }
return responseJson; 
 }

`

(_returnResponse check if it has data or error status, check at the end of the file).

This uses the conventional 'package:http/http.dart' and returns just one result. While the method sseGet:

  Future<EventSource> sseGet(String url) async {
     print("Called RestApiService:sseGet($url)");
    try {
      EventSource eventSource = await EventSource.connect(baseUrl + url,
          headers: await AuthService().getSseHeaderWithToken());
      return eventSource;
    } on SocketException {
      throw FetchDataException('No Internet connection');
    }
  }

Works the same way, but returns the EventSource object which is a stream, and continues to stream data till it's closed. You can check th method .getSseHeaderWithToken()) in the file auth_service.dart.

  Future<Map<String, String>> getSseHeaderWithToken() async {
    FirebaseUser user = await firebase.currentUser();
    var token = (await user.getIdToken()).token;
    return {
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'Accept': 'text/event-stream',
      'Authorization': 'Bearer $token',
    };
  }

It just prepares the header with the bearer token.

I hope it helps. I just tested again the code and it works great! Let me know your feedbacks.