使用标题配方的Apollo授权不起作用

时间:2018-04-16 08:39:10

标签: reactjs graphql apollo-client

我正在学习如何使用graphql和apollo制作一个反应应用程序。

首先,我能够创建一个从服务器返回帖子的查询:

(在我的app.js文件中)

<Query
    query={gql`
      {
        feed {
          id
          title
        }
      }
    `}
  >
    {({ loading, error, data }) => {
      if (loading) return <p>...loading...</p>;
      if (error) return <p>ERROR ! Try reloading</p>;

      return data.feed.map(feed => (
        <div key={feed.id}>{`Title: ${feed.title}`}</div>
      ));
    }}
  </Query>
);

有效。

然后,我想制作需要授权的查询和突变。由于服务器需要我跟踪的标题this recipe

(在我的index.js文件中)

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';

import registerServiceWorker from './registerServiceWorker';
import App from './App/App';

const GRAPHQL_API_URI = 'https://shopozor-server.herokuapp.com/';

const httpLink = createHttpLink({
  uri: GRAPHQL_API_URI,
});

const authLink = setContext((_, { headers }) => {
   // get the authentication token from local storage if it exists
   const token = localStorage.getItem('token');
  // return the headers to the context so httpLink can read them
  return {
     headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    }
  }
});

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

ReactDOM.render(
  <ApolloProvider client={client}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </ApolloProvider>,
  document.getElementById('root')
);
registerServiceWorker();

然后我之前的查询再也没有了。我收到了错误的有效负载,而不是帖子。并在控制台中写入了错误消息:

[Network error]: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

调试后,我可以知道引用的index.js文件位于apollo-boost模块中,该模块以

开头
"use strict"

另外我发现了

createHttpLink({
   uri: GRAPHQL_API_URI,
});   

没有使用我给它的链接,而是使用空字符串。

现在我没有想法。有人可以帮我解决这个问题吗?

由于

2 个答案:

答案 0 :(得分:2)

我的一位朋友发现了这个问题。我正在使用

import ApolloClient from 'apollo-boost';

而不是

import { ApolloClient } from 'apollo-client';

是具有相同名称的不同包。我以为apollo-boost只是一个使用apollo-client的捆绑包,但没有。 如果我做出这个微小的改变,它就会起作用。

apollo-boost还不支持所有的apollo功能,即使它提供了一个开箱即用的工作客户端,我也不能用它来做所有事情。看看this article

答案 1 :(得分:0)

您需要先创建中间件。以下是我如何运作

import { ApolloLink } from 'apollo-client-preset';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';

const httpLink = new HttpLink({ uri: GRAPHQL_API_URI });

// Middleware to set the headers
const middlewareAuthLink = new ApolloLink((operation, forward) => {
  const token = localStorage.getItem('token');
  const authorizationHeader = token ? `Bearer ${token}` : null
  operation.setContext({
    headers: {
      authorization: authorizationHeader,
    },
  });

  return forward(operation);
 });

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