Как исправить ошибку неверного заголовка аутентификации, исходящую от клиента Apollo

Я пытаюсь подключить свое приложение для реагирования к api backend hasura с помощью Apollo Client, но получаю следующую ошибку:

Ошибка: ошибка GraphQL: неверный заголовок авторизации

Понятия не имею, чем это вызвано.

Я знаю, что получаю действительный токен идентификатора от Cognito, потому что могу вставить его в консоль Hasura, и он отлично работает.

Я действительно просто вставил пример авторизации apollo в свой файл index.js и вставил свой uri. Я начал использовать apollo-boost, но перешел на apollo-client из-за той же ошибки. Очевидно, это не помогло. Я поискал в Интернете и не нашел ничего, что могло бы иметь отношение к этому, что, вероятно, означает, что я делаю что-то глупое.

Вот мой код apollo-client из моего index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import ApolloClient from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloProvider } from 'react-apollo';
import { Auth } from 'aws-amplify';

async function getSession() {
    Auth.currentSession().then(res=>{
        let idToken = res.getIdToken()
        let jwt = idToken.getJwtToken()
        //if I console log jwt here I can paste it into hasura and it works
        return jwt
      })
  }

const token = getSession()

//copied from apollo docs:
const httpLink = createHttpLink({
    uri: 'https://api.example.com/v1/graphql',
  });

const authLink = setContext((_, { headers }) => {
    return {
      headers: {
        ...headers,
        authorization: token ? `Bearer ${token}` : "",
      }
    }
  });

const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache()
  });

вот ошибка:

Error: GraphQL error: Malformed Authorization header
at new ApolloError (bundle.esm.js:76)
at ObservableQuery.getCurrentResult (bundle.esm.js:200)
at ObservableQuery.currentResult (bundle.esm.js:163)
at Query._this.getQueryResult (react-apollo.esm.js:247)
at finish (react-apollo.esm.js:434)
at Query.render (react-apollo.esm.js:441)
at finishClassComponent (react-dom.development.js:15319)
at updateClassComponent (react-dom.development.js:15274)
at beginWork (react-dom.development.js:16262)
at performUnitOfWork (react-dom.development.js:20279)
at workLoop (react-dom.development.js:20320)
at renderRoot (react-dom.development.js:20400)
at performWorkOnRoot (react-dom.development.js:21357)
at performWork (react-dom.development.js:21267)
at performSyncWork (react-dom.development.js:21241)
at requestWork (react-dom.development.js:21096)
at scheduleWork (react-dom.development.js:20909)
at Object.enqueueForceUpdate (react-dom.development.js:11632)
at Query.push../node_modules/react/cjs/react.development.js.Component.forceUpdate (react.development.js:355)
at Query._this.updateCurrentData (react-apollo.esm.js:214)
at Object.error (react-apollo.esm.js:197)
at notifySubscription (Observable.js:157)
at onNotify (Observable.js:196)
at SubscriptionObserver.error (Observable.js:253)
at bundle.esm.js:541
at Array.forEach (<anonymous>)
at iterateObserversSafely (bundle.esm.js:540)
at Object.onError [as error] (bundle.esm.js:482)
at invoke (bundle.esm.js:1532)
at bundle.esm.js:1565
at bundle.esm.js:1986
at Set.forEach (<anonymous>)
at bundle.esm.js:1984
at Map.forEach (<anonymous>)
at QueryManager.broadcastQueries (bundle.esm.js:1982)
at bundle.esm.js:2109
at Object.next (Observable.js:333)
at notifySubscription (Observable.js:152)
at onNotify (Observable.js:196)
at SubscriptionObserver.next (Observable.js:248)
at bundle.esm.js:1079
at Set.forEach (<anonymous>)
at Object.next (bundle.esm.js:1078)
at notifySubscription (Observable.js:152)
at onNotify (Observable.js:196)
at SubscriptionObserver.next (Observable.js:248)
at notifySubscription (Observable.js:152)
at onNotify (Observable.js:196)
at SubscriptionObserver.next (Observable.js:248)
at bundle.esm.js:107

К тому же я получаю ошибки от браузера, потому что запрос ничего не вернул.

Вот что есть в chrome console в заголовке graphql:

General:
Request URL: https://api.example.com/v1/graphql
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: 137.242.2.135:8080
Referrer Policy: no-referrer-when-downgrade

Response:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: authorization,content-type
Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,OPTIONS
Access-Control-Allow-Origin: https://example.com
Access-Control-Max-Age: 1728000
Content-Type: text/plain charset=UTF-8
Date: Thu, 18 Jul 2019 17:42:21 GMT
Server: Caddy, Warp/3.2.27

Request
Provisional headers are shown
Access-Control-Request-Headers: authorization,content-type
Access-Control-Request-Method: POST
Origin: https://example.com
Referer: https://example.com/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36

Любая помощь будет оценена по достоинству.


person Chris S    schedule 18.07.2019    source источник
comment
Является ли запрос, вызывающий эту ошибку, стандартным или подпиской? Кроме того, заголовки, которые вы показываете, предназначены для предполетного запроса, а не для фактического запроса, который должен быть следующим. Есть шанс опубликовать заголовки из этого последующего запроса (который обычно должен содержать заголовок авторизации).   -  person Thomas Hennes    schedule 19.07.2019
comment
Кроме того, как вы обрабатываете заголовок авторизации на стороне API?   -  person Thomas Hennes    schedule 19.07.2019


Ответы (1)


Значение, присвоенное token, имеет тип Promise, а не строку, как вы ожидали.

Поскольку getSession() является асинхронной функцией, она возвращает обещание.

Эта строка:

const token = getSession()

присваивает обещание, а не его разрешенное значение token.

Вам нужно дождаться разрешения обещания, прежде чем присваивать результат token.

person Tal Z    schedule 07.08.2019