What Sign in method to use best?

Viewed 70

We are having a flutter app (ios, android, web), where users are signed in via username & password. We are also using google firebase since its powerful and easy to integrate.

The username and password mainly belongs to the website where we are gathering data at. (As example - If they use the website without the app, and they change the password, after that he wont be able to login to the app)

Now the mentionned websites host is giving us API access, login via OpenId to get the access token for the API. Because we are a safety risk since we store the passwort of the users too!

For the API access we dont really need to store Username and password of the user, since they are redundant anyway. But if we want to add a feature (for example message sending or further data storage) we need to have the user signed in into firebase.

Upt to now we are using for (first) signin the following snippet:

 firebaseAuth.createUserWithEmailAndPassword(
          email: email, password: password);

and for already signed in users :

 firebaseAuth.signInWithEmailAndPassword(
              email: email, password: password);

Notice that similar credentials are also using to login on the API. (Since the user is there already registered)

How can we login on firebase with said information without asking twice for a password ond username (once for us, and once for the API) ?

We already tried :

await firebaseAuth.signInWithCustomToken(token)

with the jwl token from the OpenId, of course it did not work because the token did not contain the uid reference.

1 Answers

SOLUTION

Create a Firebase Cloud Function just like described in Firebase Cloud Functions.

Be aware that if you want to create a customtoken, the cloud functions need rights. On initializeApp(..)

admin.initializeApp({
     serviceAccountId: '{App_Name}@appspot.gserviceaccount.com',
 });

So the correct service account has to be selected, you also have to give him the rights to generate tokens. (See => Stackoverflow Question

The Cloud Function does then look the following way :

export const functionName= functions.https.onRequest(async (request, response) => {

const id = request.query.id;
const passcode = request.query.passcode; // not really needed

// add other passcodes for different authentications
if (passcode == "{COMPARE SOMETHING}") {
    await admin.auth().createCustomToken(id).then((customToken) => {
        response.status(200).send({
            'id': id,
            'customToken': customToken
        });
    }).catch((error) => {
        response.status(500).send({
            'ErrorMessage': "No token could be generated",
            "Error": error
        });
    });
}
else {
    response.status(500).send({
        'ErrorMessage': "Passcode wrong"
    });
}
});

On the other hand we have the code on the mobile app :

  // Get JWT Token
  Map<String, dynamic> jwtpayload = 
   Jwt.parseJwt(response_decoded['id_token']); // use import 'package:jwt_decode/jwt_decode.dart';
  final queryParameters = {
    'id': jwtpayload ['sub'],
    'passcode': 'APassCode',
  };
  final uri = Uri.https('us-central1-{yourApp}.cloudfunctions.net',
      '/{functionName}', queryParameters);
  final cloud_function_api_call = await client.post(uri);
  var decoded_cloud_function_api_call =
      jsonDecode(cloud_function_api_call.body);

And at the end :

      await firebaseAuth.signInWithCustomToken(
      decoded_cloud_function_api_call['customToken']);

I hope it helps others facing a similar issue.

Related