如何修复来自 Apollo 客户端的格式错误的身份验证标头错误

Posted

技术标签:

【中文标题】如何修复来自 Apollo 客户端的格式错误的身份验证标头错误【英文标题】:How do I fix Malformed authentication header error coming from Apollo client 【发布时间】:2019-11-27 18:15:29 【问题描述】:

我正在尝试使用 Apollo Client 将我的 react 应用程序连接到 hasura 后端 api,但我收到以下错误:

错误:GraphQL 错误:格式错误的授权标头

我不知道是什么原因造成的。

我知道我从 Cognito 获得了一个有效的 id 令牌,因为我可以将它粘贴到 Hasura 控制台中并且它工作正常。

我真的只是将 apollo 授权示例粘贴到我的 index.js 文件中并放入我的 uri。我开始使用 apollo-boost,但由于同样的错误而去了 apollo-client。这显然没有帮助。我搜索了互联网,找不到任何与此相关的内容,这可能意味着我在做一些愚蠢的事情。

这是我的 index.js 中的 apollo 客户端代码:

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 控制台在 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

任何帮助将不胜感激。

【问题讨论】:

触发此错误的查询是标准查询还是订阅?此外,您显示的标头用于飞行前请求,而不是 actual 请求,后者应该是以下请求。您可以发布后续请求的标头(通常应包含您的“授权”标头)。 另外,您如何处理 API 端的“授权”标头? 【参考方案1】:

分配给token 的值是Promise 类型,而不是您期望的字符串。

由于getSession() 是一个异步函数,因此它返回一个promise。

这一行:

const token = getSession()

将承诺而不是其解析值分配给token

在将结果分配给token之前,您需要等待承诺解决。

【讨论】:

以上是关于如何修复来自 Apollo 客户端的格式错误的身份验证标头错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Apollo 客户端的初始化中使用来自 React 的全局数据?

Rails、Graphql、Apollo 客户端的 Auth Token 无效

如何重置 Apollo 客户端的 useMutation 钩子

如何从 Apollo 客户端的 useQuery 获取响应头

Apollo express 没有快速护照会话

如何在来自客户端的 graphql 查询中添加 hmac?