首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获取AccessToken

如何获取AccessToken
EN

Stack Overflow用户
提问于 2019-09-14 09:31:49
回答 2查看 1.7K关注 0票数 1

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

这就是我正在做的事情。

App.js

代码语言:javascript
复制
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>
  );
}

Layout.js

代码语言:javascript
复制
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

代码语言:javascript
复制
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。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-14 19:47:57

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

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

更新:

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

Layout.js

代码语言:javascript
复制
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

代码语言:javascript
复制
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;
票数 0
EN

Stack Overflow用户

发布于 2019-09-14 09:42:27

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57931814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档