Apollo graphql 将标头设置为 authmiddleware 不起作用
Posted
技术标签:
【中文标题】Apollo graphql 将标头设置为 authmiddleware 不起作用【英文标题】:Apollo graphql setting header to authmiddleware not working 【发布时间】:2020-01-04 22:00:55 【问题描述】:我正在使用 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 函数并没有达到我的预期。我想我应该对 async 和 await 有更多的了解,但我不明白真正的问题是什么。
我从控制台收到的错误消息是jwt malformed
。请告诉我如何解决此问题
【问题讨论】:
async function
总是返回一个承诺,所以你会得到一个待处理的承诺。你能尝试做 ApolloLink 回调async
并设置"X-JWT": await getToken()
如果我这样做,它会给我另一个错误消息Network error: inner.subscribe is not a function
。 @AsafAviv
【参考方案1】:
问题是你没有等待承诺。
这意味着它应该是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】:尝试直接使用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;
【讨论】:
【参考方案3】: 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,
// ...
]);
【讨论】:
以上是关于Apollo graphql 将标头设置为 authmiddleware 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何从 graphQL apollo 突变或查询上的 cookie 更新授权标头
如何将标头添加到 ionic 4 / Apollo GraphQL App