【发布时间】:2020-01-18 20:18:07
【问题描述】:
所以我想出了如何设置一个中间件来处理我的身份验证令牌,以及在需要时获取新的。问题是,这里有一个边缘情况,当 promise 被解决后,操作在没有设置正确的标头的情况下被转发,导致另一个可能未经身份验证的调用。我觉得这里的技巧很简单,但我似乎无法弄清楚。有没有办法将承诺的结果返回到封闭的函数?我没有找到太多的运气,但也许还有另一种方法。这是设置我的中间件和 Apollo 客户端的代码:
const authLink = new ApolloLink((operation, forward) => {
operation.setContext(({ headers = {} }) => {
const token = localStorage.getItem('token');
const tokenExp = token ? decodeJWT(token).exp : null;
const currentTime = Date.now() / 1000;
if(token && tokenExp >= currentTime) {
// Check if token is expired. If so, get a new one and THEN
// move forward
headers = { ...headers,authorization: token ? `Bearer ${token}` : "", };
return { headers };
} else {
// TODO: This would be replaced with the token service that actually
// takes an expired token and sends back a valid one
return fetch('http://localhost:4000/topics', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `mutation LOGIN_USER(
$email: String
$password: String!
) {
login(email: $email, password: $password) {
id
token
}
}
`,
variables: {
email: "test@test.com",
password: "test"
}
}),
}).then(response => {
return response.json()
})
.then(({ data: { login: { token } }}) => {
// Put updated token in storage
localStorage.setItem('token', token);
headers = { ...headers,authorization: token ? `Bearer ${token}` : "", };
return { headers };
});
}
});
return forward(operation);
});
/**
* Setup the URLs for each service
*/
const httpTopicsServiceLink = createHttpLink({
uri: 'http://localhost:4000/topics',
});
/**
* Create the client instance for each GraphQL server URL
*/
export const TopicsClient = new ApolloClient({
link:authLink.concat(httpTopicsServiceLink),
cache: new InMemoryCache(),
});
【问题讨论】:
-
如果
setContext正在返回一个Promise,你不能在其中添加一个then语句并转发到那里吗? -
你是什么意思?我尝试将 .then 添加到操作中,但我收到错误消息告诉我
Cannot read property 'then' of undefined :/
标签: reactjs react-apollo apollo-client