Почему API Google ReCaptcha допускает неверный секретный ключ и / или неверный ответ токена пользователя? - PullRequest
0 голосов
/ 19 января 2020

Посмотрите на код ниже. Это на стороне сервера. Как вы видите, я вызываю API Google ReCaptcha с неверным секретным ключом и неверным ответом токена пользователя. Знаешь что? Оно работает! Точнее: Google ReCaptcha API не отвечает без исключения (, т.е.: my catch не достигнуто). Почему? Это не ожидаемое поведение, верно?

/**
 * Verifies a Recaptcha filled by the user in his Android app.
 * 1. Success: returns the JSON response
 * 2. Failure: throws the error
 **/
exports.verifyRecaptcha = functions.https.onCall((data, context) => {

    const user_response_token = data.userResponseToken;
    if(user_response_token === null || user_response_token === '') {
        throw new functions.https.HttpsError('invalid-argument', 'The function must be called with an adequat user response token.');
    }

    const remote_url = 'https://recaptcha.google.com/recaptcha/api/siteverify';
    const secret = '<MY_REAL_SECRET_KEY>';  // Original value: 'https://www.google.com/recaptcha/api/siteverify';  #  Moises' value: https://recaptcha.google.com/recaptcha/api/siteverify

    var options = {
        method: 'POST',
        uri: remote_url,
        body: {secret: 'Foo', response: 'Bar'},
        // body: {secret: secret, response: user_response_token},
        json: true
    };

    return rp(options)
            .then(parsedBody => {
                return {code: 'Success', message: 'You are actually a human (this msg is for test purposes).'};
            })
            .catch(error => {
                throw new functions.https.HttpsError('unknown', error);
            });
});

А ниже код приложения Android:

final SafetyNetApi.RecaptchaTokenResponse response = task.getResult();
assert response != null;
final String userResponseToken = response.getTokenResult();
if (!userResponseToken.isEmpty()) {
    final HashMap<String, String> the_data = new HashMap<>();
    the_data.put("userResponseToken", userResponseToken);
    FirebaseFunctions.getInstance()
            .getHttpsCallable("verifyRecaptcha")
            .call(the_data)
            .continueWith(new Continuation<HttpsCallableResult, Void>() {
                @Override
                public Void then(@NonNull final Task<HttpsCallableResult> task) {
                    if(context.isDestroyed() || context.isFinishing()) {
                        return null;
                    }

                    if(!task.isSuccessful()) {
                        Exception e = task.getException();
                        if (e instanceof FirebaseFunctionsException) {
                            FirebaseFunctionsException ffe = (FirebaseFunctionsException) e;
                            System.out.println(ffe.getMessage());
                        }

                        return null;
                    }

                    callback.onAsking();
                    return null;
                }
            });
} else {
    callback.onFailureUserResponseTokenIsEmpty();
}

1 Ответ

1 голос
/ 20 января 2020

документы предполагают, что такие ошибки, как invalid-input-secret / invalid-input-response, появятся в поле error-codes ответа.

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

Пока мы смотрим документы, я должен указать что вы, вероятно, хотите обратиться к полю success, прежде чем предположить, что ваш пользователь - человек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...