Apollo graphql 设置 header 到 authmiddleware 不工作

Apollo graphql setting header to authmiddleware not working

我正在使用 react-native 和 apollo 客户端,如果我尝试通过存储在 AsyncStorage 中的 jwt 设置 header,它似乎不起作用。
其他不需要 header 的解析器工作得很好。我的代码如下。

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 函数没有达到我的预期。我想我应该对 async 和 await 有更多的了解,但我不明白真正的问题是什么。

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

问题是您没有等待承诺。 这意味着它应该是 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;

尝试直接使用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;
    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,
      // ...
      
    ]);