Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom callback schemes for desktop using deep links #121

Open
Robert-Stackflow opened this issue Aug 21, 2024 · 2 comments
Open

Custom callback schemes for desktop using deep links #121

Robert-Stackflow opened this issue Aug 21, 2024 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@Robert-Stackflow
Copy link

The package protocol_handler is used to register and handle custom protocols, which also supports desktop platforms.So I thought I could implement the redirect callback through this plugin.The example code is as follows:

import 'dart:async';

import 'package:flutter_web_auth_2_platform_interface/flutter_web_auth_2_platform_interface.dart';
import 'package:protocol_handler/protocol_handler.dart';
import 'package:url_launcher/url_launcher.dart';

/// Implements the plugin interface using an internal server
class AuthProtocolListener implements ProtocolListener {
  /// Creates a new instance of the [AuthProtocolListener]
  const AuthProtocolListener(this.onReceivedUrl);

  /// Callback for when a URL is received
  final Function(String) onReceivedUrl;

  @override
  Future<void> onProtocolUrlReceived(String url) async {
    onReceivedUrl.call(url);
  }
}

/// Implements the plugin interface using an internal server (currently used by
/// Windows and Linux).
class FlutterWebAuth2ProtocolPlugin extends FlutterWebAuth2Platform {
  /// Registers the server implementation.
  FlutterWebAuth2ProtocolPlugin() {
    _protocolListener = AuthProtocolListener((url) async {
      if (url.contains(_callbackUrl)) {
        _handleUriCallback(url);
        protocolHandler.removeListener(_protocolListener);
      }
    });
  }

  ///[optional] CallbackUrl is used to match whether the received URI
  ///matches the redirect address
  String _callbackUrl = '';
  late AuthProtocolListener _protocolListener;

  Completer<String>? _completer;

  void _handleUriCallback(String uri) {
    if (_completer != null && !_completer!.isCompleted) {
      _completer!.complete(uri);
    }
  }

  @override
  Future<String> authenticate({
    required String url,
    required String callbackUrl,
    required String callbackUrlScheme,
    required Map<String, dynamic> options,
  }) async {
    _callbackUrl = callbackUrl;
    protocolHandler.addListener(_protocolListener);
    ///Block the thread until the _handleUriCallback method is actively called
    _completer = Completer<String>();

    await launchUrl(Uri.parse(url));

    return _completer!.future;
  }

  @override
  Future clearAllDanglingCalls() async {
    ///If the user cancels the authentication process, the _completer will
    ///never be completed. This will cause the thread to hang indefinitely.
    ///This method is used to clear all dangling calls.
    _handleUriCallback('');
  }
}
  1. Before performing this operation, developers need to modify their code according to protocol_handler to support the application receiving the URI.At the same time, developers also need to pay attention to registering the same schemes as the parameter callbackUrlScheme of the authenticate function.
  2. To avoid receiving an incorrect callback URI, you can match the received URI by specifying the callbackUrl.
  3. By using custom callback schemes, developers can avoid security risks caused by loopback addresses.For example, Google has disabled the use of loopback addresses as redirect url.
  4. Compared with the method using Webview, the oauth flow of this method is more similar with the oauth flow of other native Windows applications. Moreover, when I use Webview, I will encounter the problem of application crashing.
@ThexXTURBOXx
Copy link
Owner

Moreover, when I use Webview, I will encounter the problem of application crashing.

Could you maybe provide a crash log regarding this? Is it this error?

I am not quite sure whether yet a third method to authenticate on Windows and/or Linux is the solution - each way introduces more and more packages that flutter_web_auth_2 depends on. Is it really worth it?

@Robert-Stackflow
Copy link
Author

Robert-Stackflow commented Aug 23, 2024

Could you maybe provide a crash log regarding this? Is it this error?

The reason for the crash should be due to the desktop_webview_window package, after opening the window to verify the success of the window when the window is closed there will be a chance to cause crashing, I learned through the issues of desktop_webview_window that this may be a problem with flutter's engine.

I am not quite sure whether yet a third method to authenticate on Windows and/or Linux is the solution - each way introduces more and more packages that flutter_web_auth_2 depends on. Is it really worth it?

In my case, Since the webview approach doesn't look that elegant, I chose to use a compromise approach. I modified the flutter_web_auth_2 package in my project, removed the method of using webview and introduced the protocol_handler package. As of now, it works fine in my project, you can check out my implementation at the repository CloudOTP

It is too troublesome to implement OAuth on the desktop. I think this is also a way to provide other developers with a idea for them to choose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants