【发布时间】:2018-04-13 20:43:06
【问题描述】:
我是 apollo/graphql 的新手,我正在尝试在一个新建项目中正确完成我的身份验证。我的身份验证提供商是 AWS cognito。我写了一个 cognito helper 模块来与之交互。
虽然我不太确定如何将我的 apollo 客户端与我的身份验证状态同步。
export const authenticate = (username: string, password: string) => {
const authDetails = new AuthenticationDetails({
Username: username,
Password: password,
})
const cognitoUser = getCognitoUser(username)
return new Promise((resolve, reject) => {
cognitoUser.authenticateUser(authDetails, {
onSuccess: result => {
resolve(result)
},
onFailure: err => {
reject(err)
},
})
})
}
export const getCurrentUserToken = () => {
return new Promise((resolve, reject) => {
const currentUser = userPool.getCurrentUser()
if (currentUser) {
currentUser.getSession((error, session) => {
if (error) {
reject(error)
}
resolve(session.getIdToken().getJwtToken())
})
} else {
resolve(null)
}
})
}
export const logout = () => {
const currentUser = userPool.getCurrentUser()
if (currentUser) {
currentUser.signOut()
}
}
现在我只是使用这些函数通过在我的反应组件处理程序中调用它们来处理我的登录。我配置了一个 apollo-link 来添加 auth 标头。在后端将我的 JWT 令牌数据注入到上下文中,并在后端实现 currentUser 查询解析器。
const resolvers = {
RootQuery: {
currentUser: (obj, args, context) =>
context.tokenData
? {
id: context.tokenData.sub,
name: context.tokenData.name,
email: context.tokenData.email,
username: context.tokenData['cognito:username'],
}
: null,
},
}
在我的 react 应用布局中,我有一个组件 UserPanel,它查询 currentUser 查询。
const CURRENT_USER_QUERY = gql`
query {
currentUser {
name
}
}
`
export default graphql(CURRENT_USER_QUERY)(UserPanel)
当我现在登录时,显然 UserPanel 不会更新其 currentUser 查询,除非我正在重新加载页面。虽然我也很难找到同步它们的好解决方案。
我正在考虑使用 apollo-link-state 通过 graphql 突变实现我的登录,以便在本地执行此操作,并在有人登录/注销时观察这些以重新获取。我不确定这是否可行,因为在我看来,此链接无法解析其变异解析器中的异步内容(例如承诺)。
我正在考虑的另一个选择是将身份验证过程与 apollo 客户端完全分离,并可能使用Observables 实现一些身份验证发布系统,并让反应组件在身份验证状态发生变化时重新获取查询。
我非常不确定如何继续,而且我正在考虑的每个解决方案都不是推荐的方法。
【问题讨论】:
-
你做了什么?
标签: graphql apollo react-apollo apollo-client