Invalid response of GraphQL request via CORS and valid response via GraphiQL processing authentication with JWT

955 Views Asked by At

The problem is that I always receive a 400 response code without any payload. Even something goes wrong graphql passes with code 200 and payload with error block. That fact, that GraphiQl works fine, tells me that settings and schema are correct. So... I'm stuck. Maybe, any ideas, where to look?

I don't think it fails because of cors itself. My app worked well under DRF. I decided to try new for me technology and overwrite app using GQL.

My Origin: http://127.0.0.1:8080

Here my Apollo Client:

const cache = new InMemoryCache();
const link = new HttpLink({
  uri: "http://127.0.0.1:8000/graphql/",
  credentials: "include", // cookies enabled
  headers: {
    "X-Csrftoken": getTokenCsrf(),  
    "Content-Type": "application/json"
  },
  fetchOptions: {
    mode: "cors"
  }
});

const client = new ApolloClient({
  cache,
  link
});

There is my request (values of vars coming from the form via the state):

const AUTH_QUERY = gql`
  mutation TokenAuth($username: String!, $password: String!) {
    tokenAuth(username: $username, password: $password) {
      token
    }
  }
`;

I used react-apollo-hook for performing query:

const [sendCreds, loading, error] = useMutation(AUTH_QUERY);
const handleSubmit = e => {
    sendCreds({
      variables: { username: state.username, password: state.password }
    });
};

my Schema (according docs):

class Mutation(graphene.ObjectType):
    token_auth = graphql_jwt.ObtainJSONWebToken.Field()
    verify_token = graphql_jwt.Verify.Field()
    refresh_token = graphql_jwt.Refresh.Field()

schema = graphene.Schema(query=Query, mutation=Mutation)

Processing this query from GraphiQL gives me a valid response. GraphiQL is run on http://127.0.0.1:8000/graphql on another tab of browser.

Query:

mutation TokenAuth($username: String!, $password: String!) {
  tokenAuth(username: $username, password: $password) {
    token
  }}

Variables:

   {"username": "qwerty", "password": "qwerty"}

Response:

{
  "data": {
    "tokenAuth": {
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InF3ZXJ0eSIsImV4cCI6MTU2NjMwMTkwNiwib3JpZ0lhdCI6MTU2NjMwMTYwNn0.NzgecEfFcnsrudcgrlZyBCC1rutoVJFciUI-ugFq9Fg"
    }}}
1

There are 1 best solutions below

0
On

So, the problem was solved. Don't forget, that when you press the button without explicitly defined type, the type "submit" is used.

<form >
  <div className="input-field">
    <input type="text" id="username" />
    <input type="password" id="password" />        
    <button
      type="button"  // that string solved my problem.
      onClick={handleSubmit}
    >
      {msg}
    </button>      
  </div>
</form>

When you press the submit-typed button, render is called and response tries to dispatch content to the unmounted component. But if your button has type "button", request works fine. I hope my torment will save someone his time.