/flutter_oauth

Experiment with doing oauth in flutter web apps

Primary LanguageC++Apache License 2.0Apache-2.0

flutter_oauth

Experiment with doing oauth in flutter web apps

To run it

flutter run -d chrome --web-port=8080
  • We need to pin the web port because the redirect uri is hard coded to localhost:8080 in gcp.dart and assets/oauth2redirect.html

How it works

This uses the Authorization Code Flow with Proof Key for Code Exchange(PKCE) to obtain a refresh token and access token from Google. It uses tetranetsrl/oauth2_client to handle the oauth flow. The refresh token is stored in local storage and can be used to obtain an access token when needed.

The library works by having the user login inside a popup window and then send the authorization request. BrowserWebAuth is the code that handles this. It is invoked from requestAuthorization. The authorization request returns a redirect. The redirect URL should return an html page which posts an event back to the main window in which the flutter app is running. In this example assets/oauth2redirect.html is the html page that is returned. It includes the JS code

<script type="text/javascript">
  window.onload = function() {
    const urlParams = new URLSearchParams(window.location.search);
    const code = urlParams.get('code');
    if(code) {
      window.opener.postMessage(window.location.href, "http://localhost:8080/assets/oauth2redirect.html");
    }
  }
</script>

which posts the message back to the main window. BrowserWebAuth handles the code by closing the window and using the authorization code to obtain the flow.

Importantly, this means that the authorization code passes through the server in order to be passed along to the client. This is why PKCE is used. Since the server doesn't know the code challenge and verifier, it can't exchange the auth code for the access token. Only the flutter app which knows the code challenge and verifier can do that.

Implicit Flow

Based on the links below, it seems like the implicit flow is no longer recommended for SPA apps.

By extension I don't think the extension_google_sign_in_as_googleapis_auth package is the right flutter package to use when accessing a user's Google Data. As explained in StackOverflow Question, I think that package uses the implicit flow. However, that package maybe suitable when using Google just to signin to your app (i.e. OIDC).

Asset Serving paths

When you deploy your app the oauth2redirect.html will be served it at

https://${YOURURL}/assets/assets/oauth2redirect.html

That is all assets are placed under the directory assets and the path is relative to the root of pubspec.yaml. So in this case because we have assets in an assets directory the URL is duplicated.

This is confusing because when running in debug you can also access the file at

https://localhost/assets/oauth2redirect.html

But this path won't work in production so you should use the former.

For reference see [flutter/flutter#67655](flutter/flutter#67655

Resources