如何在用户认证后才设置Apollo客户端?[英] How to set up Apollo client only after user authenticates?

本文是小编为大家收集整理的关于如何在用户认证后才设置Apollo客户端?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我对如何构建我的react/graphql(apollo)应用程序有点困惑,直到用户对用户进行认证/登录.

目前我有一个:

class App extends Component {
  render() {
    return (
      <ApolloProvider client={client}>
        <Provider store={store}>
          <Router>
            <div>
              <ul>
                <li><Link to="/">Home</Link></li>
                <li><Link to="/login">Log In</Link></li>
                <li><Link to="/signup">Sign Up</Link></li>
              </ul>
              <AuthenticatedRoute exact path="/" component={HomePage} />
              <Route path="/login" component={LoginPage} />
              <Route path="/signup" component={SignupPage} />
            </div>
          </Router>
        </Provider>
      </ApolloProvider>
    );
  }
}

这是网络接口的创建:

const networkInterface = createNetworkInterface({
  uri: process.env.NODE_ENV === 'development'
    ? 'http://localhost:3000/graphql'
    : 'TBD',
});

networkInterface.use([
  {
    applyMiddleware(req, next) {
      if (!req.options.headers) {
        req.options.headers = {}; // Create the header object if needed.
      }

      getUserSession()
        .then(session => {
          // get the authentication token from local storage if it exists
          // ID token!
          req.options.headers.authorization = session
            .getIdToken()
            .getJwtToken();
        })
        .catch(err => {
          console.error('oh, this is bad');
        })
        .then(next);
    },
  },
]);

我如何组织此内容,以便仅初始化Apollo客户端并设置一次,并且只有在用户身份验证?

之后

我想知道我是否可以使用 withapollo 以某种方式访问​​客户直接并以这种方式完成GraphQl auth&Connection.

想法2

使用redux跟踪用户状态,用connect跟踪App.当用户进行身份验证时,这会触发触发App's componentDidUpdate的redux状态变化,该更改可能会创建Apollo的网络接口,从而在App中导致重新渲染,从而将授权client传递到.

推荐答案

我通常会收听从redux设置为true的" isloggedin"字段.设置为true时,我渲染完整的应用程序并添加身份验证标头,以便该函数将JWT令牌添加到所有以后的请求中.

import React, { Component } from 'react';
import { ApolloProvider } from 'react-apollo';
import makeStore from '../../store';
import createClient from '../../ApolloClient';

class Sample extends Component {
    login() {
       // login logic here;
    }
    routeTo() {
        // use props or state;
        let isLoggedIn = this.props.isLoggedIn || this.state.loggedIn;
        if(isLoggedIn) {
            const client = createClient(myToken);
            const store = makeStore(myToken);
                return (
                <ApolloProvider store={store} client={client} > 
                    <Routes screenProps={this.state}  />
                </ApolloProvider>);
        } else {
            return <LoginUI onPress={()=>this.login()}/>;
        }
    }
    render() {
        return(
         <div>
            {this.routeTo()}
          </div>
        );
}

其他推荐答案

我使用apolloclient示例 http://dev.apollodata.com/react/auth.html#标题

networkInterface.use([{
  applyMiddleware(req, next) {
    if (!req.options.headers) {
      req.options.headers = {};  // Create the header object if needed.
    }
    // get the authentication token from local storage if it exists

    const token = localStorage.getItem('token');
    req.options.headers.authorization = token ? `Bearer ${token}` : null;
    next();
  }
}])

块applyMiddleware将始终在获取GraphQl Server之前运行,因此您只需要在注销时登录和删除时设置localStorage.

其他推荐答案

  const token = request.authToken; // localhost.get('authetoken)
  return {
    headers: {
      ...headers,
      Authorization: `Bearer ${token}`,
    },
  };
});```

setContext will take care of that for you 


本文地址:https://www.itbaoku.cn/post/1938051.html

问题描述

I'm a bit confused on how to structure my React/GraphQL (Apollo) app when no connection should be made until the user authenticates/logs in.

Currently I have this:

class App extends Component {
  render() {
    return (
      <ApolloProvider client={client}>
        <Provider store={store}>
          <Router>
            <div>
              <ul>
                <li><Link to="/">Home</Link></li>
                <li><Link to="/login">Log In</Link></li>
                <li><Link to="/signup">Sign Up</Link></li>
              </ul>
              <AuthenticatedRoute exact path="/" component={HomePage} />
              <Route path="/login" component={LoginPage} />
              <Route path="/signup" component={SignupPage} />
            </div>
          </Router>
        </Provider>
      </ApolloProvider>
    );
  }
}

Here's the creation of the network interface:

const networkInterface = createNetworkInterface({
  uri: process.env.NODE_ENV === 'development'
    ? 'http://localhost:3000/graphql'
    : 'TBD',
});

networkInterface.use([
  {
    applyMiddleware(req, next) {
      if (!req.options.headers) {
        req.options.headers = {}; // Create the header object if needed.
      }

      getUserSession()
        .then(session => {
          // get the authentication token from local storage if it exists
          // ID token!
          req.options.headers.authorization = session
            .getIdToken()
            .getJwtToken();
        })
        .catch(err => {
          console.error('oh, this is bad');
        })
        .then(next);
    },
  },
]);

How do I organize this so that the Apollo client is only initialized and set up once, and only after the user has authenticated?

I'm wondering if I could use withApollo to somehow access the client directly and complete the GraphQL auth & connection that way.

Idea 2

Use Redux to track user state, wrap App with connect. When the user authenticates, this triggers a Redux state change which triggers App's componentDidUpdate which could create the network interface for Apollo, causing a re-render in App which would pass an authorized client into <ApolloProvider client={client}>.

推荐答案

I typically listen for a "isLoggedIn" field to be set to true from redux. When it's set to true, I render the full app and add the authentication header so that the function adds the JWT token to all future requests.

import React, { Component } from 'react';
import { ApolloProvider } from 'react-apollo';
import makeStore from '../../store';
import createClient from '../../ApolloClient';

class Sample extends Component {
    login() {
       // login logic here;
    }
    routeTo() {
        // use props or state;
        let isLoggedIn = this.props.isLoggedIn || this.state.loggedIn;
        if(isLoggedIn) {
            const client = createClient(myToken);
            const store = makeStore(myToken);
                return (
                <ApolloProvider store={store} client={client} > 
                    <Routes screenProps={this.state}  />
                </ApolloProvider>);
        } else {
            return <LoginUI onPress={()=>this.login()}/>;
        }
    }
    render() {
        return(
         <div>
            {this.routeTo()}
          </div>
        );
}

其他推荐答案

I use ApolloClient example http://dev.apollodata.com/react/auth.html#Header

networkInterface.use([{
  applyMiddleware(req, next) {
    if (!req.options.headers) {
      req.options.headers = {};  // Create the header object if needed.
    }
    // get the authentication token from local storage if it exists

    const token = localStorage.getItem('token');
    req.options.headers.authorization = token ? `Bearer ${token}` : null;
    next();
  }
}])

the block applyMiddleware will always run before fetching to GraphQL server, so you just need to set localStorage when login and delete when logout.

其他推荐答案

  const token = request.authToken; // localhost.get('authetoken)
  return {
    headers: {
      ...headers,
      Authorization: `Bearer ${token}`,
    },
  };
});```

setContext will take care of that for you