Flutter Web: OAuth authentication through external window

Guillaume Roux
ITNEXT
Published in
4 min readFeb 27, 2021

--

A few days ago I’ve published this article:

While it might have been helpful to some readers I have found a much better way to manage authentication on Flutter Web. Thanks to my friend and colleague Meï M. for his help.

Usually when you are authenticating on a website or a web application using 3rd party services you connect your account through an external window. This process avoid the website you were on to reload entirely after the redirection. It is the main issue implied with the method described in my previous article.

So today let’s fix that and implement OAuth2 flow using an external authentication window. Still by using Twitch’s API so people who followed the previous article won’t be too lost.

Prerequisites

  • Create your initial Flutter application
  • A valid Twitch and Twitch Developer account
  • Some basic HTML and JS knowledge

Set Up

Before we start coding let me explain what will be our authentication flow. We are going to open Twitch authentication URL in a new window by passing as parameters in the URL our client_id and the redirect_uri . The main difference compared to the previous article is that our redirect_uri will not be used to redirect to our application after the authentication process but to a static HTML page which sole purpose will be to send to our main application window the data we are looking for. In this case it will be the OAuth token contained in our URL.

In terms of code the actions we want to accomplish are:

  • Open Twitch Authentication Page in an External Window
  • After authentication redirect to our Static Page
  • Send the URL containing the authentication token from our Static Page to the Main Page
  • Catch the token in our Main Page
  • Close the External Window

Create our Static Page

First thing to do before even trying to open the external window is to create the static HTML page we are going to be redirected to.

Here is the code for the static.html page that you will have to create inside the web/ folder:

static.html

It is basically an empty HTML page, the important part is inside <script> . To be able to send our page’s URL containing our authentication token we are using the method postMessage() which allows us to communicate with our main window through the window.opener reference (Window.postMessage doc). We are sending the window.location.href , our URL containing the token.

Open an External Window

Now how to open the external window you may ask ? Well it is actually quite simple as we have an abstraction in the dart:html library:

So to open our external window we call the method window.open and adding width and height options so it will open a new window instead of a tab. We are keeping the window’s reference inside our _popupWin variable so we will be able to close it programatically after we receive our access token.

The only thing that is left is to do is to add a listener to get the message sent by our external window.

Listen to Message

And once again Dart is well made as we have an abstraction for message listening:

As you can see here we are relying on window.onMessage to listen to our postMessage from our static page. It is important to check beforehand if the event received contains access_token as the Twitch login itself sends a message to confirm that the authentication succeeded. And you just have to parse your URL, you have a working example here but you can do this however you want.

To end our authentication flow we close the window using our previously saved reference _popupWin .

Conclusion

And this is it ! I hope that the steps were clear and that you have understood them all. As for the previous article this should work with any OAuth2 flow. This works in a much more “web” manner without needing to reload your application entirely. This is the last time I will bother you with authentication in Flutter Web as I consider this solution much more final and useable.

If this article was helpful to you then do not hesitate to leave a comment, share it or clap so it might help more people.

As always here is the source code I have based my article on:

--

--