arnemolland / sigv4

Dart library for signing AWS requests with Signature Version 4
MIT License
17 stars 23 forks source link

FormatException (FormatException: Invalid empty scheme (at character 1) #27

Open BartusZak opened 3 years ago

BartusZak commented 3 years ago

sign extenstion does not work in example.dart.

Request('GET', Uri.parse(path)).sign(client);
Exception ``` Unhandled exception: FormatException: Invalid empty scheme (at character 1) :// ^ #0 _Uri._fail (dart:core/uri.dart:1538:5) #1 new _Uri.notSimple (dart:core/uri.dart:1371:9) #2 Uri.parse (dart:core/uri.dart:956:17) #3 Sigv4Client.signedHeaders package:sigv4/src/client.dart:137 #4 HttpExtension.sign package:sigv4/…/extensions/http.dart:6 #5 main package:sigv4/main.dart:56 #6 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:283:19) #7 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) ```
MohammedNoureldin commented 3 years ago

Same here, have you found any solution?

BartusZak commented 3 years ago

Hey @MohammedNoureldin,

No, I did not.

I used a standard solution and sign it manually with interceptors.

 CognitoDioClient({required authenticationRepository})
      : _authenticationRepository = authenticationRepository,
        assert(authenticationRepository != null) {
    _cognitoDioClient.options.baseUrl = serverUrl;

    _cognitoDioClient.interceptors
        .add(InterceptorsWrapper(onRequest: (options, handler) {
      final String? idToken = _sharedPreferencesManager!.getString('idToken');

      options.headers[HttpHeaders.authorizationHeader] = 'Bearer $idToken';
      return handler.next(options);
    }, onResponse: (response, handler) {
      return handler.next(response);
    }, onError: (DioError e, handler) async {
      // Do something with response error
      _cognitoDioClient.lock();
      _cognitoDioClient.interceptors.responseLock.lock();
      _cognitoDioClient.interceptors.errorLock.lock();

      RequestOptions options = e.response!.requestOptions;

      final bool _isIdTokenValid =
          await _authenticationRepository.isIdTokenValid();

      if (!_isIdTokenValid) {
        try {
          await _authenticationRepository.refreshTokens();
        } catch (e) {
          print('Refresh Token failed');
        }
        _cognitoDioClient.request(options.path, options: options as Options?);
      }

      _cognitoDioClient.unlock();
      _cognitoDioClient.interceptors.responseLock.unlock();
      _cognitoDioClient.interceptors.errorLock.unlock();
      return handler.next(e);
    }));

Please keep in mind that storing a plain credentials in Session or Local Storage of the Browser is not recommended. There should be an addictionel layer of security (hashed/ encodedor something).

Perfect solution (regarding to other articles) is to store credentials inside Cookie.

Be aware :)

MohammedNoureldin commented 3 years ago

@BartusZak I am bit confused. The code is not very clear to me. How is this supposed to sign URL/Headers? And why is it a Standard solution?

MohammedNoureldin commented 3 years ago

Whatever, I implemented my own Dart code that signs the AWS URLs:

https://github.com/MohammedNoureldin/aws-url-signer