【问题标题】:apollo client 2.0 graphql react auth阿波罗客户端 2.0 graphql 反应身份验证
【发布时间】: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


【解决方案1】:

我没有关于你的 React 设置的全貌,但我开始了。可能是 Apollo 客户端正在本地缓存 CURRENT_USER_QUERY 并向您显示先前查询的结果。您可以在查询中尝试network-only 选项:

export default graphql(CURRENT_USER_QUERY, { options: {fetchPolicy: 'network-only' }})(UserPanel)

我在 React 中有一个 AppContainer,它是我的父组件。它检查用户是否登录:

const loggedInUser = gql`
  query loggedInUser{
    user {
      id
      role
    }
  }`


export default graphql(loggedInUser, { options: {fetchPolicy: 'network-only' }})(AppContainer)

然后在我的 UserProfile 页面上,我使用数据容器来获取数据,然后再将其传递给 UserProfile 子组件。我认为loggedInUser 查询会自动更新阿波罗商店中的用户。有了它,apollo-client 意识到它需要重新获取userQuery。这有帮助吗?

const userQuery = gql`
  query userQuery {
    user {
      id
      name
      email
      role
      company
    }
  }
`
export default graphql(userQuery, {name: 'userQuery'})(UserDataContainer);

【讨论】:

    猜你喜欢
    • 2021-07-13
    • 2021-04-03
    • 2017-10-15
    • 2019-02-15
    • 2019-12-09
    • 2020-03-18
    • 2021-06-28
    • 2019-07-06
    • 1970-01-01
    相关资源
    最近更新 更多