【问题标题】:How to fetch AccessToken如何获取 AccessToken
【发布时间】:2019-09-14 01:31:49
【问题描述】:

我在 React 中使用以下插件 (@axa-fr/react-oidc-context) 来启用 AzureAd 身份验证。现在我需要在认证完成后访问 ApolloClient 中的 access_token。我不确定如何在 ApolloClient 等非反应组件中获取 access_token。

这就是我正在做的事情。

App.js

import React from "react";
import { HashRouter, Route, Switch } from "react-router-dom";
import { AuthenticationProvider, withOidcSecure } from "@axa-fr/react-oidc-context";
import { IDENTITY_CONFIG } from "./utils/configuration";
// components
import Layout from "./Layout";

export default function App() {
  return (
    <AuthenticationProvider configuration={IDENTITY_CONFIG}>
      <HashRouter>
        <Switch>
          <Route path="/" component={withOidcSecure(Layout)} />
        </Switch>
      </HashRouter>
    </AuthenticationProvider>
  );
}

布局.js

import React from "react";
import { Route, Switch, withRouter } from "react-router-dom";
import { ApolloProvider } from "@apollo/react-hooks";
import client from "./apollo";

import Dashboard from "./pages/dashboard";

function Layout(props) {
  return (
    <>
      <ApolloProvider client={client}>
        <Switch>
          <Route exact path="/" component={Dashboard} />
        </Switch>
      </ApolloProvider>
    </>
  );
}

export default withRouter(Layout);

apollo.js

import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import { ApolloLink, split } from "apollo-link";
import { setContext } from "apollo-link-context";
import { HttpLink } from "apollo-link-http";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";

import { useReactOidc } from "@axa-fr/react-oidc-context";

const { oidcUser } = useReactOidc();

console.log(oidcUser.access_token)

const httpUri = process.env.REACT_APP_SERVER_URL
  ? process.env.REACT_APP_SERVER_URL
  : "https://48p1r2roz4.sse.codesandbox.io";
const wsUri = httpUri.replace(
  /^https?/,
  process.env.REACT_APP_ENV === "dev" ? "ws" : "wss"
);

const httpLink = new HttpLink({
  uri: httpUri
});

const wsLink = new WebSocketLink({
  uri: wsUri,
  options: {
    lazy: true,
    reconnect: true
    // connectionParams: () => {
    //   return { headers: { Authorization: getAuthHeader() } };
    // }
  }
});

const authLink = setContext((_, { headers }) => {
  //   const auth = getAuthHeader()

  return {
    headers: {
      ...headers
      //   Authorization: auth,
    }
  };
});

const terminatingLink = split(
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query);
    return kind === "OperationDefinition" && operation === "subscription";
  },
  wsLink,
  authLink.concat(httpLink)
);

const link = ApolloLink.from([terminatingLink]);
const cache = new InMemoryCache();

const client = new ApolloClient({
  link,
  cache
});

export default client;

我正在尝试在 apollo.js 文件中提取访问令牌,但它会抛出错误,提示我无法访问非 React 组件中的 React Hooks。

【问题讨论】:

  • 代码的哪一部分正在尝试获取访问令牌?

标签: javascript reactjs oidc-client


【解决方案1】:

以前从未使用过这个库,但看起来它使用higher order component 将道具传递给您传递给withOidcSecure 的包装组件。您应该能够访问通过您的Layout 组件中的props 提供的任何数据。尝试在其中使用console.log(props),看看它返回了什么,我不确定到底传递了什么数据。

【讨论】:

    【解决方案2】:

    由于令牌信息在身份验证后存储在 sessionStorage 中,因此我能够从会话存储中提取 access_token 信息并作为授权标头分配给我的 ApolloClient。

    如果有更好的解决方案,请告诉我。

    更新:

    我们可以使用 useReactOidc 来获取 access_token 作为传递给 Apollo 客户端的 props,而不是获取会话存储的令牌。请查看更新后的代码。

    布局.js

    import React from "react";
    import { Route, Switch, withRouter } from "react-router-dom";
    import { ApolloProvider } from "@apollo/react-hooks";
    import { useReactOidc } from "@axa-fr/react-oidc-context";
    import client from "./apollo";
    
    import Dashboard from "./pages/dashboard";
    
    function Layout(props) {
      const { oidcUser } = useReactOidc();
    
      return (
        <>
          <ApolloProvider client={client(oidcUser.access_token)}>
            <Switch>
              <Route exact path="/" component={Dashboard} />
            </Switch>
          </ApolloProvider>
        </>
      );
    }
    
    export default withRouter(Layout);
    

    apollo.js

    import { InMemoryCache } from "apollo-cache-inmemory";
    import { ApolloClient } from "apollo-client";
    import { ApolloLink, split } from "apollo-link";
    import { setContext } from "apollo-link-context";
    import { HttpLink } from "apollo-link-http";
    import { WebSocketLink } from "apollo-link-ws";
    import { getMainDefinition } from "apollo-utilities";
    
    const httpUri = process.env.REACT_APP_SERVER_URL
      ? process.env.REACT_APP_SERVER_URL
      : "http://localhost:8080/v1/graphql";
    const wsUri = httpUri.replace(
      /^https?/,
      process.env.REACT_APP_ENV === "dev" ? "ws" : "wss"
    );
    
    const httpLink = new HttpLink({
      uri: httpUri
    });
    
    const wsLink = token =>
      new WebSocketLink({
        uri: wsUri,
        options: {
          lazy: true,
          reconnect: true,
          connectionParams: () => {
            return { headers: { Authorization: `Bearer ${token}` } };
          }
        }
      });
    
    const authLink = token =>
      setContext((_, { headers }) => {
        return {
          headers: {
            ...headers,
            Authorization: `Bearer ${token}`
          }
        };
      });
    
    const terminatingLink = token =>
      split(
        ({ query }) => {
          const { kind, operation } = getMainDefinition(query);
          return kind === "OperationDefinition" && operation === "subscription";
        },
        wsLink(token),
        authLink(token).concat(httpLink)
      );
    
    const link = token => ApolloLink.from([terminatingLink(token)]);
    const cache = new InMemoryCache();
    
    const client = token =>
      new ApolloClient({
        link: link(token),
        cache: cache
      });
    
    export default client;
    

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2013-11-08
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 2020-04-21
      相关资源
      最近更新 更多