Как пройти проверку подлинности с помощью облачной функции Google при использовании приложения Firebase с входом в Google? - PullRequest
0 голосов
/ 21 февраля 2020

Я новичок ie (примерно 6 месяцев или около того), и я создаю приложение на Android (Java), которое использует FireBase Auth с Google Sign In. (только через несколько дней NodeJS разоблачения) Другими словами, мой конечный пользователь входит в учетную запись Google. Эта часть (я думаю) пока работает довольно хорошо. Я активно использую базу данных Firestore для многих вещей в приложении.

Итак, я дошел до того, что хочу использовать (Callable) облачные функции с триггерами HTTP. (никогда раньше этого не делал) Я пытаюсь получить подтверждение концепции, работающей в это время. Фактическая функция работает, и я могу вызвать ее из моего приложения.

Похоже, я не могу понять, как сделать функцию "частной"; как в «добавлении надлежащих членов» к облачной функции, которые имеют право вызывать функцию.

Я пробовал несколько разных вещей методом пробной ошибки, но сначала позвольте мне показать, что у меня есть.

Это функция облака, и я передаю произвольную строку в качестве теста, работает хорошо: (до тех пор, пока "allUsers" имеют роль / право вызывать функцию; другими словами, когда функция опубликована c.


exports.createTest = functions.https.onCall((data, context) => {

const text = data.text;

const uid = context.auth.uid;
const name = context.auth.token.name || null;
const email = context.auth.token.email || null;

console.log('UID: ', uid);
console.log('Name: ', name);
console.log('Email: ', email);
console.log('Message: ', text);



});

Вышеупомянутая функция запускается в моем Android / Java код, подобный следующему: (Я думаю, что этот код взят из Google Doc / Sample / Example

    private FirebaseFunctions mFunctions;


    ...

    private void testing() {


        mFunctions = FirebaseFunctions.getInstance();

        Log.e(LOG_TAG, "Testing executed!");

        String testMessage = "Hello Hello Testing 123 Mic Check";


        createTest(testMessage)
                .addOnCompleteListener(new OnCompleteListener<String>() {
                    @Override
                    public void onComplete(@NonNull Task<String> task) {
                        if (!task.isSuccessful()) {
                            Exception e = task.getException();
                            if (e instanceof FirebaseFunctionsException) {
                                FirebaseFunctionsException ffe = (FirebaseFunctionsException) e;
                                FirebaseFunctionsException.Code code = ffe.getCode();
                                Object details = ffe.getDetails();

                                Log.e(LOG_TAG, "FFE: " + ffe.getMessage() );
                                Log.e(LOG_TAG, "Code: " + code);
                                Log.e(LOG_TAG, "Details:" + details);
                            }

                            // ...
                        }

                        // ...
                    }
                });

    }

    private Task<String> createTest(String text) {
        // Create the arguments to the callable function.
        Map<String, Object> data = new HashMap<>();
        data.put("text", text);
        data.put("push", true);

        return mFunctions
                .getHttpsCallable("createTest") //this is the function name
                .call(data)
                .continueWith(new Continuation<HttpsCallableResult, String>() {
                    @Override
                    public String then(@NonNull Task<HttpsCallableResult> task) throws Exception {
                        // This continuation runs on either success or failure, but if the task
                        // has failed then getResult() will throw an Exception which will be
                        // propagated down.
                        String result = (String) task.getResult().getData();

                        if (result != null) {
                            Log.e(LOG_TAG, "Result: " + result);
                        }
                        return result;
                    }
                });
    }

Только когда мне добавили «allUsers» с ролью / правом «вызвать функцию облака», тогда я чтобы это работало. Мое понимание запросов HTTP и тому подобного довольно ограничено, что не облегчает задачу.

Я попытался использовать опции «allAuthenticatedUsers», которые, как я полагал, сработали бы, потому что я действительно аутентифицирую свои Пользователи в приложении через Firebase / Google Sign In. Эта облачная функция должна быть доступна только для a) прошедших проверку пользователей или b) пользователей указанного домена c. (У меня есть домен, скажем, @ testorganization.com) Или, если я смогу идентифицировать свое конкретное приложение (ключ api?), Это тоже сработает.

В тот момент, когда я добавляю члена "allAuthenticatedUsers" с ролью для вызова функции (и удаления «allUsers») ничего не происходит. Я также пытался добавить весь домен, но это не сработало. на работу.

В моем Node JS коде я фактически получаю UID аутентифицированного пользователя, поэтому кажется, что какая-то информация аутентификации пользователя уже обменивается.

С этими знаниями Я могу (успешно попробовал это) получить UID и перепроверить это по моей базе данных и проверить пользователя таким образом, но кажется ненужным, и я должен быть в состоянии заставить работать разрешения (полностью заблокировать функцию) Плюс это заняло очень долго, просто заканчиваю sh эту перекрестную проверку. Или это довольно стандартная процедура?

Как это -> * 102 5 *

const usersRef =  admin.firestore().collection('users').doc(uid)

usersRef.get()
  .then((docSnapshot) => {
    if (docSnapshot.exists) {
      usersRef.onSnapshot((doc) => {
       console.log('User Type logged in: ', doc.data().userCategory)
       console.log('User Title: ', doc.data().userTitle)
      });
    } else {
      console.log('User does not exist')
    }

});

Редактировать:

Поэтому, не выяснив, как полностью отключить функцию, я обнаружил, что вместо перекрестной проверки моих пользователей я могу просто проверить аутентификацию следующим образом:

if (context.auth){
  //user is auth'd
} else {
  //no auth
}

Я думаю, это немного лучше. (но все же технически не препятствует доступу к функции?!)

Большое спасибо за любую помощь. Очень признателен.

Edit2:

Вот снимок экрана области облачной консоли (для ролей / привилегий облачной функции), на которую я ссылаюсь:

https://imgur.com/cBsjaaL

1 Ответ

1 голос
/ 21 февраля 2020

Используя функцию Callable Cloud, если вы хотите гарантировать, что только аутентифицированные пользователи могут запускать ее бизнес-логи c, вам на самом деле не нужно настраивать какие-либо дополнительные «роли / привилегии облачных функций», как показано внизу ваш вопрос.

По умолчанию с функцией Callable Cloud вы получите, когда доступно, «Firebase Authentication и токены FCM, автоматически включаемые в запросы», и он «автоматически десериализует тело запроса и проверяет токены аутентификации», как объяснено в do c.

Так что вам просто нужно следовать do c и использовать параметр context. Как вы упомянули в своем вопросе, вы можете проверить подлинность пользователя, выполнив:

if (context.auth) {
  //...
}

Если вы хотите проверить электронную почту пользователя, вы должны сделать:

exports.addMessage = functions.https.onCall((data, context) => {

    const uid = context.auth.uid;
    return admin.auth().getUser(uid)
      .then(userRecord => {
          const userEmail = userRecord.email;
          //....
       })
       .catch(function(error) {
           console.log('Error fetching user data:', error);
          // Send back an error to the front end
          // See https://firebase.google.com/docs/functions/callable#handle_errors
       });

});

Вы другие примеры того, как «работать» с пользователями с Admin SDK , можно найти здесь в do c.

...