在用户进行身份验证/登录之前,如果不进行任何连接,我对如何构建我的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身份验证&amp;连接那样。
使用Redux跟踪用户状态,使用App
包裹connect
。当用户进行身份验证时,会触发Redux状态更改,触发App
componentDidUpdate
,这可能会为Apollo创建网络接口,导致App
中的重新呈现将授权client
传递给<ApolloProvider client={client}>
。
答案 0 :(得分:1)
我通常会听一个&#34; isLoggedIn&#34;要从redux设置为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>
);
}
答案 1 :(得分:1)
我使用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
并在注销时设置删除。
答案 2 :(得分:0)
const token = request.authToken; // localhost.get('authetoken)
return {
headers: {
...headers,
Authorization: `Bearer ${token}`,
},
};
});```
setContext will take care of that for you