Flutter's recent beta release has turned quite a few heads in the mobile development scene recently. As a result, we've decided to open source our Slack OAuth library for Flutter (and optionally, Firebase). Here's a short rundown of what it's all about.

Google's mobile UI framework Flutter is the new kid on the block in terms of cross platform mobile app development (Android and iOS). It's a very promising framework doing all of the rendering directly in 2D, avoiding the use of OEM widgets. This means it can guarantee consistency between iOS and Android apps, even though it also provides the tools to differentiate in different themes (e.g. Cupertino vs. Material) depending on target device.

Dart is the programming language used for writing apps in Flutter. Since both Dart and Flutter haven't seen much usage outside of Google yet (even though both have been used in production apps), it means that there still are a limited amount of plugins/packages/libraries available for the framework.

A great list of open source Flutter plugins called awesome-flutter is being curated and updated weekly by Robert Felker.

Slack OAuth

For an internal app at Kunstmaan | Accenture Interactive which required easy authentication for employees and contractors, we decided to use Slack OAuth for authentication. It meant we wouldn't need to use our own authentication logic; someone who could successfully log in to our Slack Team could also use our internal app. The use case for this is quite clear: You want to authenticate people through their Slack credentials, but you don't plan using any other features of the Slack API.

 

Slack OAuth flow. In our first use case, we can actually stop after step 4, since the user has been authenticated on Slack at that point. (© Slack)

Flutter and Slack OAuth

Since there was no (up to date) generic library which handled OAuth locally on device out of the box and we wanted to stay within the Slack style guidelines, we decided to implement an easily reusable Slack OAuth library for Flutter. This way our library would not only be able to handle the OAuth sign-in logic, but also be responsible for the UI during that flow (including a properly styled "Sign in with Slack" button widget matching Slack's style guidelines).

Our Flutter "Sign in with Slack" button widget.

Providing the "Sign in with Slack" button as a carefully crafted widget (even including the fonts used by Slack) instead of an image gave us multiple advantages:

  • The button can be 100% styled depending on its state.
  • Clean interface for starting and ending the OAuth flow:
    • Our SlackButton widget will handle everything including opening a WebView to handle the Slack OAuth, listen on redirects with authentication codes,...
    • The only thing you need to provide is an onSuccess (and onCancelled/onFailure) callback.
new SlackButton(
    clientId: "XXX_CLIENT_ID_XXX",
    clientSecret: "XXX_CLIENT_SECRET_XXX",
    redirectUrl: "https://kunstmaan.github.io/flutter_slack_oauth/success.html",
    onSuccess: () {
        Scaffold.of(context).showSnackBar(new SnackBar(
            content: new Text('Slack Login Success'),
        ));
    },
    onFailure: () {
        Scaffold.of(context).showSnackBar(new SnackBar(
            content: new Text('Slack Login Failed'),
        ));
    },
    onCancelledByUser: () {
        Scaffold.of(context).showSnackBar(new SnackBar(
            content: new Text('Slack Login Cancelled by user'),
        ));
    },
),

Our SlackButton widget handles the full Slack OAuth flow, you only need to provide some onSuccess and onFailure callbacks.

Optional Firebase integration

On the other hand, you might want to be able to combine your Slack authentication with some actual backend logic. For example, you might want to store each user's Slack Access Token, or you might want to populate your own database with the users from your Slack team automatically.

For these requirements, we created the Slack OAuth with Firebase for Flutter library. This library is built upon our basic Slack OAuth for Flutter library, but provides a FirebaseSlackButton widget which takes a Firebase Functions endpoint as parameter. We also provide some sample code for your Firebase Functions endpoint in the same repository. Our Firebase Functions will handle the Slack OAuth directly on Firebase, and return a Custom Token to our Flutter library. That Custom Token is then used to authenticate a Firebase User. All this is automatically handled by our library, so the FirebaseSlackButton can be used as shown below:

new FirebaseSlackButton(
    clientId: "XXX_CLIENT_ID_XXX",
    clientSecret: "XXX_CLIENT_SECRET_XXX",
    redirectUrl: "https://XXX-FIREBASE-PROJECT-XXX.firebaseapp.com/completed.html",
    firebaseUrl: "https://XXX-FIREBASE-PROJECT-XXX.firebaseapp.com/index.html",
    onSuccess: () async {
        // get Firebase User:
        FirebaseUser user = await _auth.currentUser();

        Scaffold.of(context).showSnackBar(new SnackBar(
            content: new Text('Logged in with Slack ID ' + user.uid),
        ));
    },
    onFailure: () {
        Scaffold.of(context).showSnackBar(new SnackBar(
            content: new Text('Slack Login Failed'),
        ));
    },
    onCancelledByUser: () {
        Scaffold.of(context).showSnackBar(new SnackBar(
            content: new Text('Slack Login Cancelled by user'),
        ));
    },
),

In our Firebase Functions sample code, we also show how to populate a Cloud Firestore with two collections, one containing the most recent Slack access token for each user, and one containing user data. By utilising our flow for storing these Slack access tokens, you can easily make Slack API calls directly from your Flutter app, by getting the access token for the current user as follows:

FirebaseUser user = await _auth.currentUser();

DocumentSnapshot snapshot = await Firestore.instance.document("slackAccessTokens/" + user.uid).get();
String slackAccessToken = snapshot.data["accessToken"];
UserList userList = await slack.getUsers(slackAccessToken);

Finally, our libraries also provide some basic data structures such as UserList and User, to quickly get started with some prototyping without needing to parse all of the Slack API calls manually.

You can check out both libraries on Github and Pub, and they're featured on Awesome Flutter as well.

Pull requests for new features or improvements are always welcome!

Written by

Thomas Stockx

Mobile developer

Follow @thomasstockx