Apollo graphql设置头到authmiddleware不起作用

时间:2019-09-01 15:19:24

标签: react-native async-await apollo apollo-client asyncstorage

我正在使用react-native和apollo客户端,如果我尝试通过存储在AsyncStorage中的jwt设置标头,则似乎无法正常工作。
其他不需要头的解析器效果很好。我的代码如下所示。

import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink } from "apollo-link";
import { createHttpLink } from "apollo-link-http";
import AsyncStorage from "@react-native-community/async-storage";

const cache = new InMemoryCache();

const getToken = async () => {
  const token = await AsyncStorage.getItem("jwt");

  if (token) {
    return token;
  } else {
    return null;
  }
};

const httpLink = new createHttpLink({
  uri: ""
});

const authLink = new ApolloLink((operation, forward) => {
  operation.setContext({
    headers: {
      "X-JWT": getToken()
      // this is where I set headers by getToken function
      // If I change function getToken to real token in string type, it works then
    }
  });

  return forward(operation);
});

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

export default client;

就像我在代码中评论的那样,调用getToken函数无法按预期工作。我想我应该对异步和等待有更多的了解,但是我不了解真正的问题是什么。

我从控制台收到的错误消息是jwt malformed。请让我知道如何解决此问题

3 个答案:

答案 0 :(得分:1)

尝试直接使用setContext

import { ApolloClient } from "apollo-client";
import { createHttpLink } from "apollo-link-http";
import { setContext } from "apollo-link-context";
import { InMemoryCache } from "apollo-cache-inmemory";
import AsyncStorage from "@react-native-community/async-storage";

const httpLink = createHttpLink();

const authLink = setContext(async (_, { headers }) => {
  const token = await AsyncStorage.getItem("jwt");

  return {
    headers: {
      ...headers,
      "X-JWT": token || null
    }
  };
});

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

export default client;

答案 1 :(得分:0)

问题在于您没有等待诺言。 这意味着它应该是await getToken()。为了使此工作正常,ApolloLink函数也应为async

这会稍微降低您的性能,因为在每次请求时,它都会从您的AsyncStore中读取令牌。 我会那样做:

import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink } from "apollo-link";
import { createHttpLink } from "apollo-link-http";
import AsyncStorage from "@react-native-community/async-storage";

const cache = new InMemoryCache();

let token
const getToken = async () => {
  if(token) return token;

  token = await AsyncStorage.getItem("jwt");

  return token || null;
};

const httpLink = new createHttpLink({
  uri: ""
});

const authLink = new ApolloLink(async (operation, forward) => {
  operation.setContext({
    headers: {
      "X-JWT": await getToken()
      // this is where I set headers by getToken function
      // If I change function getToken to real token in string type, it works then
    }
  });

  return forward(operation);
});

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

export default client;

答案 2 :(得分:0)

import { setContext } from '@apollo/client/link/context';

// import getJwtToken // return string

const authMiddleware = setContext(async (operation) =>{
  const token = await getJwtToken();
    return {
      headers: {
        authorization: token || null,
      },
    };
});


const link = ApolloLink.from([
  authMiddleware,
  // ...
  
]);