用户认证后如何设置 Apollo 客户端?

Posted

技术标签:

【中文标题】用户认证后如何设置 Apollo 客户端?【英文标题】:How to set up Apollo client only after user authenticates? 【发布时间】:2017-11-14 13:02:31 【问题描述】:

在用户验证/登录之前不应建立连接时,我对如何构建我的 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 身份验证和连接。

想法 2

使用 Redux 跟踪用户状态,用 connect 包裹 App。当用户进行身份验证时,这会触发 Redux 状态更改,从而触发 AppcomponentDidUpdate,这可能会为 Apollo 创建网络接口,从而导致 App 重新渲染,这会将授权的 client 传递给 @987654330 @。

【问题讨论】:

【参考方案1】:

我通常会在 redux 中监听“isLoggedIn”字段是否设置为 true。当它设置为 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>
        );

【讨论】:

【参考方案2】:

我使用 ApolloClient 示例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();
  
])

applyMiddleware 块会一直运行在 GraphQL 服务器之前,所以你只需要在登录时设置 localStorage 并在注销时删除。

【讨论】:

当你使用 websockets 的时候呢? (订阅-传输-ws) 只是把自己剪到这个,所以当有人回答这个问题时我会收到通知^【参考方案3】:
  const token = request.authToken; // localhost.get('authetoken)
  return 
    headers: 
      ...headers,
      Authorization: `Bearer $token`,
    ,
  ;
);```

setContext will take care of that for you 


【讨论】:

以上是关于用户认证后如何设置 Apollo 客户端?的主要内容,如果未能解决你的问题,请参考以下文章

JWT认证机制

通过 IdentityServer 认证后如何获取 WebAPI 控制器上的用户信息?

如何捕获 Google Analytics 用户 ID 并将其插入 SQL 数据库以进行后端潜在客户资格认证

客户端应用接入Apollo

jwt认证

赵强老师MongoDB管理用户的认证机制