首页 > 解决方案 > Firebase 登录后更新 ApolloClient 的标头

问题描述

当用户使用我的 react 应用程序注册时,我在发送带有 graphql 请求的授权标头时遇到问题。

我的流程是:

  1. 用户注册 Firebase,react app 收到 id 令牌。

  2. 用户被重定向到另一个页面,他们可以在其中填写更多信息。

  3. 用户点击提交,通过graphql(Apollo)向自定义后端发送请求以创建用户。

问题是当用户在二次注册页面上点击提交输入他们的名字时,发送到后端的请求不包含授权标头。如果我在单击提交之前重新加载该页面(这是在 firebase 注册成功之后),那么它会按预期工作。

index.js:

const token = localStorage.getItem(AUTH_TOKEN);

const client = new ApolloClient({
  link: new HttpLink({
  uri: 'http://localhost:9000/graphql',
  headers: {
    authorization: token ? `Bearer ${token}` : ''
  }
  }),
  cache: new InMemoryCache()
});

应用程序.js:

componentWillMount() {
  const _this = this;
  firebaseApp.auth().onAuthStateChanged((user) => {
    if (user) {
      console.log('AUTH STATE CHANGED', user);
      // If logged in...
      _this.setState({ loggedin: true });
      user.getToken()
        .then((result) => {
          localStorage.setItem(AUTH_TOKEN, result);
        });
    } else {
      // If not logged in...
      _this.setState({ loggedin: false });
    }
  });
}

SignUp.js(这是用户可以使用 firebase 进行身份验证的地方):

handleSubmit(e) {
    e.preventDefault()
    const email = this.state.email.trim()
    const password = this.state.password.trim()
    if (isEmail(email)) {
        firebaseApp
            .auth()
            .createUserWithEmailAndPassword(email, password)
            .then(() => {
              browserHistory.push('/signupcontinued');
            })
            .catch((error) => {
                // Handle Errors here.
                const errorMessage = error.message
                alert(`errorMessage: ${  errorMessage}`)
            })
    } else {
        alert('Email Address in not valid')
    }
}

SignUpContinued.js(用户在将创建用户请求发送到自定义后端之前输入他们的姓名):

const SignUpMutation = gql`
    mutation CreateUser($userInput: UserInput!) {
      user {
        create(organizationId: 3, userInput: $userInput) {
          id
          firstName
          lastName
          email
          organizationId
          balance
        }
      }
    }
`

class SignupContinued extends Component {
    render() {
      let firstname;
      let lastname;
        return (
            <div>
                <Mutation mutation={SignUpMutation}>
                  {(signup, { data }) => (
                    <div>
                      <form
                        onSubmit={e => {
                          e.preventDefault();

                          const userInput = {
                            firstName: firstname.value,
                            lastName: lastname.value,
                            email: (firebaseApp.auth().currentUser) ? firebaseApp.auth().currentUser.email : ''
                          }

                          signup({ variables: {
                              userInput
                          }}).then(() => {
                            browserHistory.push('/home')
                          });
                          firstname.value = '';
                          lastname.value = '';
                        }}
                      >
                        <input
                          placeholder='Enter First name'
                          ref={node => {
                            firstname = node;
                          }}
                        />
                        <input
                          placeholder='Enter Last name'
                          ref={node => {
                            lastname = node;
                          }}
                        />
                        <button type='submit'>Submit</button>
                      </form>
                    </div>
                  )}
                </Mutation>
            </div>
        )
    }
}

我是否正确重定向用户以便重新加载反应(并且 ApolloClient 更新其标头?或者问题与我的.then功能有关并且onAuthStateChanged在重定向之前没有完成运行?

谢谢!

标签: javascriptreactjsfirebaseapolloreact-apollo

解决方案


Apollo 客户端在 firebase 将令牌设置为 localstorage 之前从 localStorage 获取令牌数据。您应该在 firebase 设置后刷新 apollo 标头


推荐阅读