用户认证后如何设置 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 状态更改,从而触发 App
的 componentDidUpdate
,这可能会为 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 客户端?的主要内容,如果未能解决你的问题,请参考以下文章
通过 IdentityServer 认证后如何获取 WebAPI 控制器上的用户信息?