Аутентификация API Firebase Rest

В настоящее время я разрабатываю приложение с использованием базы данных Firebase Realtime, однако я решил отказаться от использования SDK для извлечения данных из db. Причина в том, что я не хочу, чтобы мой код был так тесно связан с FireBase, как только приложение будет построено, сам api будет перемещаться в пользовательский псевдоним на основе api.

Я реализовал вызовы api с использованием REST с Firebase в соответствии с документами без проблем - POST, GET, DELETE и т.д.

Проблема заключается в том, что если я включу любую аутентификацию в базе данных, в соответствии с документами, мне нужно отправить "access_token" с запросом, но я не знаю, откуда это получить. firebaseUser.getToken(true) возвращает то, что выглядит как токен JWT, который не распознается, если я отправляю его как "access_token". Я получаю 401 Unauthorized

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

Итак, мой вопрос в том, может ли кто-нибудь указать мне, как получить требуемый токен доступа, который идентифицирует, какой пользователь обращается к этому api? Параметры входа в систему, поддерживаемые моим проектом Firebase, - это Google, Facebook и Twitter.

Ответы

Ответ 1

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

REST API

Для получения токена доступа вам необходимо использовать служебную учетную запись. Пожалуйста, ознакомьтесь с руководством по использованию учетных записей службы Google. Вы можете создать учетные данные учетной записи службы в своем проекте Firebase из раздела "Учетные записи службы" консоли Firebase.

Например, один из способов создать соответствующий токен oauth2 - это Java google-api-client.

GoogleCredential googleCred = GoogleCredential.fromStream(new FileInputStream("service_account.json"));
GoogleCredential scoped = googleCred.createScoped(
    Arrays.asList(
      "https://www.googleapis.com/auth/firebase.database",
      "https://www.googleapis.com/auth/userinfo.email"
    )
);
scoped.refreshToken();
String token = scoped.getAccessToken();

Успешный запрос будет обозначен кодом статуса HTTP 200 OK. Ответ содержит извлекаемые данные:

{ "first": "Jack", "last": "Sparrow" }

API REST для базы данных принимает access_token=<TOKEN> в строке или заголовке запроса. Authorization: Bearer <TOKEN> для проверки подлинности запроса с использованием учетной записи службы.

Следующий пример демонстрирует, как вы можете использовать это с базой данных, содержащей имена пользователей. Вы бы заменили [PROJECT_ID] идентификатором вашего проекта Firebase.

facebook

Вы должны добавить Facebook SDK в свое приложение и реализовать LoginButton и LoginManager, запрашивающие некоторую информацию в виде public_profile электронного письма. Это довольно раздражает работать с Facebook SDK. Пример кода о том, как добавить это:

// Initialize Facebook Login button
mCallbackManager = CallbackManager.Factory.create();
LoginButton loginButton = (LoginButton) findViewById(R.id.button_facebook_login);
loginButton.setReadPermissions("email", "public_profile");
loginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
    @Override
    public void onSuccess(LoginResult loginResult) {
        Log.d(TAG, "facebook:onSuccess:" + loginResult);
        handleFacebookAccessToken(loginResult.getAccessToken());
    }

    @Override
    public void onCancel() {
        Log.d(TAG, "facebook:onCancel");
        // ...
    }

    @Override
    public void onError(FacebookException error) {
        Log.d(TAG, "facebook:onError", error);
        // ...
    }
});

Кроме того, в консоли разработчиков из Facebook вы должны создать учетную запись, настроить новый проект с именем пакета вашего приложения и добавить ключи SHA для отладочной и выпускной версий вашего приложения. После того, как вы все это сделаете, вы успешно получите токен из объекта LoginResult используя метод getAccessToken()

Вы можете прочитать больше об этом в официальной документации.

Google

Google проще, потому что он уже подключен к Firebase, вы должны добавить в свои google play services Gradle google play services и добавить файл google services JSON уже настроенный в вашем приложении. Вы можете получить его из консоли Firebase.

После этого вам нужно будет настроить элемент GoogleSignInOptions используя идентификатор из вашего файла JSON:

// Configure Google Sign In
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();

После этого вам просто нужно GoogleSignInApi в вашем приложении и дождаться обратного вызова onActivityResult:

private void signIn() {
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess()) {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = result.getSignInAccount();
                firebaseAuthWithGoogle(account);
            } else {
                // Google Sign In failed, update UI appropriately
                // ...
            }
        }
    }

После этого вы сможете получить токен из элемента GoogleSignInAccount. Не забудьте настроить различные ключи SHA для отладочной или выпускной версий вашего приложения, иначе вход в Google перестает работать в выпускной версии.

Вы можете прочитать больше об этом в официальной документации Firebase

щебет

Что касается Твиттера, я не работал с Твиттером, поэтому в настоящий момент я не могу вам помочь, но я предлагаю вам проверить документацию для разработчиков в Твиттере и публикацию по реализации в Firebase.

Я попытаюсь отредактировать это, когда сделаю несколько домашних снимков, проверяя, как это работает.

О токенах Firebase

Еще одна полезная вещь, о которой нужно знать - это токены Firebase id, которые уникальны для каждого пользователя и соединения в вашем приложении, позволяя вам проверить, пытается ли одна и та же учетная запись одновременно регистрироваться с разных устройств, или отправлять сообщения FCM Cloud на использовать онлайн-уведомления в вашем приложении.

Чтобы получить его, вы должны использовать объект FirebaseInstanceId используя API и метод FirebaseInstanceId.getInstance(). При этом вы получите уникальный идентификатор FirebaseInstance для вашего пользователя, когда он/она войдет в ваше приложение.

Вы можете получить его токен с помощью idInstance.getToken() и сохранить его, когда захотите, в своем приложении, чтобы проверить его и управлять им так, как вы хотите.

Документация Firebase об этом не совсем ясна, поэтому я рекомендую вам использовать следующую ссылку, она мне очень помогла реализовать ее в моем приложении.

Ответ 2

Вы можете добавить таблицу на свой сервер для USER. В этой таблице добавьте поля, такие как firebase_token, google_token, fb_token и т.д. Когда вы регистрируетесь во всех этих службах один за другим, обновите поля в таблице для пользователя. Таким образом, вы можете поддерживать users_info, а также все необходимые маркеры.