ReactJS:Apollo 客户端在用户通过身份验证后设置身份验证令牌

问题描述 投票:0回答:2

我已将 apollo 客户端与我的应用程序连接起来。最初在公共路线中没有令牌。只有用户登录后,才会获取和存储令牌。

我的问题是,一旦用户登录,我就无法在查询的标头中自动设置令牌。因为我一开始就初始化了 Apollo Client,所以我必须刷新页面才能在标头中设置令牌。从登录组件登录后,有什么方法可以设置身份验证令牌?

index.js

import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import { store } from "./redux/config-store";
import { PersistGate } from "redux-persist/integration/react";
import { persistStore } from "redux-persist";
import { ApolloProvider } from "@apollo/client";
import client from "./apollo/apollo.config";

let persistor = persistStore(store);

ReactDOM.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <BrowserRouter>
            <App />
          </BrowserRouter>
        </PersistGate>
      </Provider>
    </ApolloProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

apolloconfig.js

import { setContext } from "@apollo/client/link/context";
import { store } from "../redux/config-store";

export const getToken = () => {
  const state = store.getState();
  if (state.currentUser.currentUser) {
    return state.currentUser.currentUser.token;
  } else {
    return "";
  }
};

const httpLink = createHttpLink({
  uri: "http://localhost:4000/graphql",
});

const authLink = setContext((_, { headers }) => {
  // get the authentication token from local storage if it exists
  const token = getToken();
  // return the headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,
      authorization: `${token}`,
    },
  };
});

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

export default client;

如何在用户登录后自动设置令牌?

reactjs graphql apollo-client apollo-server
2个回答
1
投票

经过一番研究,我找到了解决方案。如果其他人遇到此问题,请发布解决方案。

在 index.js 中,使用

new ApolloClient
创建客户端并传递给
Apollo Provider
,如图所示

export const apolloClient = new ApolloClient({
  uri: "http://localhost:4000/graphql",
  cache: new InMemoryCache({
    addTypename: false,
  }),
});

ReactDOM.render(
  <React.StrictMode>
    <ApolloProvider client={apolloClient}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </ApolloProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

在需要身份验证的情况下,令牌将在各个查询中传递,如图所示,

const { loading, error, data } = useQuery(EXAMPLE_QUERY, {
    context: {
          headers: {
            authorization: `${
              user.accessToken ? user.accessToken : ""
            }`,
          },
        },
  });

我不确定这是否是最有效的解决方案。但这对我来说没有任何问题。


0
投票

这个解决方案对我有用

import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';

const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql',
});

const authLink = setContext((_, { headers }) => {
  // get the authentication token from local storage if it exists
  const token = localStorage.getItem('token');
  
  // return the headers to be used in the HTTP request
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : '',
    },
  };
});

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

© www.soinside.com 2019 - 2024. All rights reserved.