Ошибка Firebase.auth с ошибочным запросом 400

Я обнаружил странную ошибку при разработке системы с использованием Firebase с URL-адресом службы, содержащим пользовательские данные.

Пользовательские данные ниже.

    {
      "uid": "kt9Hcp2FbYbBvvIeSHHa1RbvHcv2",
      "displayName": "Anonymous 901",
      "photoURL": null,
      "email": null,
      "emailVerified": false,
      "identifierNumber": null,
      "isAnonymous": true,
      "providerData": [

      ],
      "apiKey": "MyApiKeyString",
      "appName": "MyAppName",
      "authDomain": "my.auth.domain",
      "stsTokenManager": {
        "apiKey": "MyApiKeyString",
        "refreshToken": "refreshTokenString",
        "accessToken": "accessTokenString",
        "expirationTime": 1532451863076
      },
      "redirectEventId": null
    }

Я кодирую указанные выше анонимные данные пользователя и включаю их в URL-адрес службы. (http://myserviceurl?userdata=encodedUserData)

Внутри системы, получающей этот URL-адрес, firebase создает пользовательский объект с этими пользовательскими данными, содержащимися в URL-адресе.

Цель этого URL-адреса - использовать информацию о конкретном пользователе в любом браузере.

Однако, когда я вызываю этот URL-адрес службы, иногда система хорошо создает объект пользователя, иногда возникает ошибка - 400 ошибок неверного запроса с https://www.googleapis.com/identitytoolkit/v3/relyingparty/setAccountInfo?key=MyApiKeyString

И данные об ошибках ниже,

    {
      "error": {
        "code": 400,
        "message": "TOKEN_EXPIRED",
        "errors": [
          {
            "message": "TOKEN_EXPIRED",
            "domain": "global",
            "reason": "invalid"
          }
        ]
      }
    }

Через несколько часов все работает хорошо, но я ничего не менял.

Я не смог найти точную точку ошибки, но подозреваю, что ошибка возникает при наблюдении за состоянием аутентификации или перед этим шагом.

Вот фрагменты кода

    @bind
    private makeUserLoadingPromise(): Promise<void> {
      let unSubscribe: () => void;
      return new Promise<void>((resolve, _reject) => {
        const onInitialized = this.makeOnInitializedAuthStateChanged(resolve);
        unSubscribe = this.auth.onAuthStateChanged(onInitialized);
      }).then(() => {
        unSubscribe();
        this.auth.onAuthStateChanged(this.onAuthStateChanged);
      });
    }

    @bind
    private makeOnInitializedAuthStateChanged(resolve: () => void) {
      return (user: firebase.User | null) => {
        this.user = user;
        resolve();
      };
    }

    @bind
    private onAuthStateChanged(user: firebase.User | null) {
      this.user = user;
    }

Или, может быть, это связано с expirationTime?

Я не мог найти никаких намеков на эту ситуацию.

Любой совет будет принят во внимание.


person Woojin Jeong    schedule 25.07.2018    source источник


Ответы (1)


Непонятно, что вы делаете, но похоже, что вы используете API неправильно и небезопасно. Простой пользовательский объект содержит неопределенный токен обновления. Передавать его через URL - действительно плохая идея.

Во-первых, не полагайтесь на внутренние реализации, они могут быть изменены. Чтобы получить информацию о пользователе на вашем сервере, правильный способ сделать это - получить токен идентификатора пользователя с помощью официально поддерживаемого API, например user.getIdToken(), а затем передать его на ваш сервер.

На своем сервере вы подтверждаете это с помощью Firebase Admin SDK: admin.auth().verifyIdToken(idToken). Тогда вы знаете, что это настоящий аутентифицированный пользователь. Если вам нужна полная информация о пользователе, вы можете найти ее, используя декодированный идентификатор пользователя в токене: admin.auth().getUser(decodedIdToken.sub).

person bojeil    schedule 02.08.2018