首页 文章

apollo client 2.0 graphql react auth

提问于
浏览
0

我试图在绿地项目中正确完成我的身份验证 . 我的身份验证提供程序是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()
  }
}

现在我只是通过在我的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,
  },
}

在我的反应应用程序布局中,我得到了一个组件 UserPanel ,它查询 currentUser 查询 .

const CURRENT_USER_QUERY = gql`
  query {
    currentUser {
      name
    }
  }
`

export default graphql(CURRENT_USER_QUERY)(UserPanel)

当我现在登录时,显然UserPanel不会更新其 currentUser 查询,除了我正在重新加载页面ofc . 虽然我也很难找到一个很好的解决方案来同步它们 .

我正在考虑通过graphql变异实现我的登录,使用apollo-link-state在本地执行此操作,如果有人登录/退出,请查看这些重新获取 . 我不确定这是否正常,因为在我看来,这个链接无法解析其突变解析器中的异步内容(例如promises) .

我想到的另一个选择是将auth进程与apollo客户端完全分离,并使用 Observables 实现一些auth pubsub系统,并且如果身份验证状态发生变化,让react组件重新获取查询 .

我很不确定如何继续,我正在考虑的每个解决方案都不像是推荐的方式 .

1 回答

  • 0

    我没有关于你的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意识到它需要重新获取 userQuery . 这有帮助吗?

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

相关问题