supertokens/supertokens-flutter

Web support

Opened this issue · 7 comments

Would like to have support for Flutter web applications

+1

What is the obstacle? All the dependencies support desktop and web.

Hi @maticmeznar

We have not evaluated all the changes needed to support web yet because of other priority features, so we cant speak for the effort or any blockers for this task. We welcome contributions though and would be happy to review PRs for landing this.

I have tried to get this working. The problem with google_sign_in (used in the SuperTokens docs) is, that it was never intended to be used in a browser.
Google provides the google_sign_in_web package, that is typically used to render a sign-in button with it the provided renderButton method and the signInSilently method to re-use an existing session in the browser (SSO).
With them, you can log in to a google account from flutter.

Unfortunately, there is no way to get the server auth code from the GoogleSignIn class, but there is a GoogleSignInPlugin class, that can be used for that (you can even skip the Google-rendered button and silent log-in):

  var signInPlugin = GoogleSignInPlugin();
  signInPlugin
      .initWithParams(SignInInitParameters(
        scopes: scopes,
        signInOption: SignInOption.standard,
        clientId: clientId,
      ))
      .then((_) => {
            signInPlugin
                .requestServerAuthCode()
                .then((authCode) => useServerAuthCode(authCode))
          });

The problem with google_sign_in (used in the SuperTokens docs) is, that there is no way to get the server auth code.

I have tried to use this to call the signinup endpoint:

curl --location --request POST 'http://localhost:3000/signinup' \
--header 'rid: thirdparty' \
--header 'Content-Type: application/json; charset=utf-8' \
--data-raw '{
    "thirdPartyId": "google",
    "clientType": "web",
    "redirectURIInfo": {
        "redirectURIOnProviderDashboard": "http://localhost:51917/callback/google",
        "redirectURIQueryParams": {
            "code": "...",
        }
    }
}'

and even though I have registered the redirectURIOnProviderDashboard (which is required by the SuperTokens backend) as Authorized redirect URI in the Google Could Console, I get this request error in my backend (handled in the SuperTokens middleware):

POST request to https://oauth2.googleapis.com/token resulted in 400 status with body {
  "error": "redirect_uri_mismatch",
  "error_description": "Bad Request"
}

I think this might not be a problem with the SuperTokens SDK any more, but with my Google Cloud config. If I get this working, this should do it.


Update: setting

"redirectURIOnProviderDashboard": "null",

(not nil or null in json) leads to:

You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure.
You can let the app developer know that this app doesn't comply with one or more Google validation rules.

So the login seems to work, but Google still has some issues with me using the test application.

Have you tried providing the oAuthTokens prop of the request body, and just providing the access or id token from google?

Have you tried providing the oAuthTokens prop of the request body, and just providing the access or id token from google?

oAuthTokens requires the id_token and the access_token. How do I get the access_token?

You can give just the id_token as well.. both should not be required i think.

Thank you, this worked. I had to get the credentials by awaiting the authentication field of the currentUser.
This is what I ended up with:

import 'package:google_sign_in_web/web_only.dart';

Future<Response<dynamic>> googleSignInUp(
  Dio dio,
  GoogleSignIn? googleSignIn,
) async {
  var auth = await googleSignIn?.currentUser?.authentication;
  return dio.post("/signinup",
      options: Options(headers: {
        "rid": "thirdparty",
      }),
      data: {
        "thirdPartyId": "google",
        "clientType": "web",
        "oAuthTokens": {
          "id_token": auth?.idToken,
          "access_token": auth?.accessToken,
        }
      });
}

Note, that I use the GoogleSignIn class, not GoogleSignInPlugin, because I also use the renderButton function of web_only with a listener on googleSignIn.onCurrentUserChanged.