React Native Apollo graphql将头设置为authmiddleware不工作

c0vxltue  于 2022-11-25  发布在  React
关注(0)|答案(4)|浏览(172)

我正在使用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。请告诉我如何解决此问题

cnwbcb6i

cnwbcb6i1#

尝试直接使用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;
ws51t4hk

ws51t4hk2#

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,
      // ...
      
    ]);
jecbmhm3

jecbmhm33#

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

6ojccjat4#

谢谢@ Lex dyky,这是我的最新版本

import { Auth } from "@aws-amplify/auth";
    import { ApolloClient, ApolloLink, createHttpLink, InMemoryCache } from "@apollo/client";
    import { setContext } from "@apollo/client/link/context";
    
    export const getGraphqlClient = (url: string) => {
      const getToken = async () => {
        return (await Auth.currentSession()).getIdToken().getJwtToken();
      };
    
      const authMiddleware = setContext(async (operation) => {
        return {
          headers: {
            authorization: `Bearer ${await getToken()}` || null,
          },
        };
      });
    
      const link = ApolloLink.from([authMiddleware]);
      const httpLink = createHttpLink({ uri: url });
    
      return new ApolloClient({
        link: link.concat(httpLink),
        cache: new InMemoryCache(),
      });
    };

相关问题