当前位置: 首页 > 知识库问答 >
问题:

apollo client 2.0 graphql react auth

南门洋
2023-03-14

我是Apollo/GraphQL的新手,我正试图在一个新建项目中正确地完成身份验证。我的身份验证提供程序是AWScognito。我编写了一个cognito helper模块来与它交互。

虽然我不太确定如何同步我的apollo客户端与我的auth状态。

js prettyprint-override">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()
  }
}

现在,我只是通过在react组件处理程序中调用这些函数来处理我的登录。我配置了一个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,
  },
}
const CURRENT_USER_QUERY = gql`
  query {
    currentUser {
      name
    }
  }
`

export default graphql(CURRENT_USER_QUERY)(UserPanel)

我考虑的另一个选择是将auth进程与apollo客户机完全分离,并使用Observables实现一些auth pubsub系统,如果身份验证状态发生变化,则让react组件重新执行查询。

我很不确定如何继续下去,我想的每一个解决方案都不是推荐的方式。

共有1个答案

狄雅珺
2023-03-14

我没有关于你的React设置的完整画面,但我开始了。可能是Apollo-client在本地缓存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商店中的用户。有了它,apollo-client意识到它需要refetchuserquery。那有帮助吗?

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

相关问答

相关文章

相关阅读