javascript - 从 React + Apollo GraphQL 浏览器扩展中的扩展存储中获取令牌
问题描述
我正在尝试使用 React 和 Apollo GraphQL 创建浏览器扩展。对于背景,我使用的是 ,webextension-polyfill
这就是为什么我引用browser
命名空间而不是chrome
.
在我的index.tsx
文件中,我尝试如下设置我的 Apollo 客户端:
// ... more imports ...
import App from './App'
const link = HttpLink({
uri: 'http://localhost:8000/graphql/',
});
const authLink = setContext((_, { headers }) => {
window.postMessage({ type: "GET_TOKEN" }, "*");
// I need to fetch `token` from the the result of the above postMessage
return {
headers: {
...headers,
authorization: token ? `JWT ${token}` : "",
}
}
})
export const client = new ApolloClient({
link: authLink.concat(link),
cache: new InMemoryCache()
});
ReactDOM.render(
<ApolloProvider client={client}>
<React.StrictMode>
<App />
</React.StrictMode>
</ApolloProvider>,
document.getElementById("root")
);
通常在常规网络应用程序中,您会将令牌存储在 localStorage 中,然后像这样从那里获取它localStorage.getItem("token")
。
但由于这是一个浏览器扩展,我不能使用 localStorage 并在所有选项卡中从中获取。我必须使用browser.storage.local
.
用户登录后,我可以成功保存到扩展程序browser.storage.local
,因此您可以假设令牌可用并且可以获取。
由于您无法与browser.storage.local
扩展的上下文之外进行交互,因此我必须向我的content.js
脚本发送一条消息,告诉它从存储中获取它。
这就是为什么我在window.postMessage({ type: "GET_TOKEN" }, "*");
上面。
然后在我的content.js
文件中,我收听该消息,并发送另一条带有结果的消息:
window.addEventListener("message", function (event) {
...
onDidReceiveMessage(event);
})
async function onDidReceiveMessage(event) {
if (event.data.type && (event.data.type === "GET_TOKEN")) {
const payload = JSON.parse(JSON.stringify({ type: "TOKEN_RESULT", token: await browser.storage.local.get("token") }));
window.postMessage(payload, "*");
}
}
我的问题现在是index.tsx
在我设置 Apollo 客户端期间侦听此事件并在文件中使用它。
在index.tsx
文件中,我尝试了以下内容:
const authLink = setContext((_, { headers }) => {
window.postMessage({ type: "GET_TOKEN" }, "*");
window.addEventListener("message", function (event) {
if (event.data.type && (event.data.type === "TOKEN_RESULT")) {
token = event.data.token.token
}
});
// the value of `event.data.token.token` in the listener is correct and successfully fetched
// but can only really be used in the listener, I need it available to be used below
// as part of this outer `setContext` for Apollo
return {
headers: {
...headers,
authorization: token ? `JWT ${token}` : "",
}
}
})
如果我需要在设置文件(例如用于设置 Apollo 客户端的文件)中使用它,如何在浏览器扩展的上下文中从存储中获取令牌?
任何帮助或替代方法将不胜感激。
解决方案
推荐阅读
- python - 如何提取图像中由空格分隔的子图?
- java - 使用 Duo Access Gateway 的 Android 上的 SAML 2.0
- angular - dateClass 属性仅在角度材料 matCalendar 中触发一次
- c# - 双击标签时如何更改标签的背景颜色?
- server - CPanel 共享服务器上的恶意软件
- selenium - 无法找到 web 元素,元素根据字段突出显示更改
- json - jq 的意外循环循环
- java - 在不将 Java 升级到 8 或更高版本的情况下寻找解决方法,支持 Java 1.7.0_79 中的 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 密码
- arduino - DragGO LGO1 未通过串行监视器或 ssh 命令连接
- python - 为什么我的字典值在我不告诉它的情况下发生变化,我该如何阻止它?