通过 CORS 的 GraphQL 请求的无效响应和通过使用 JWT 的 GraphiQL 处理身份验证的有效响应

Posted

技术标签:

【中文标题】通过 CORS 的 GraphQL 请求的无效响应和通过使用 JWT 的 GraphiQL 处理身份验证的有效响应【英文标题】:Invalid response of GraphQL request via CORS and valid response via GraphiQL processing authentication with JWT 【发布时间】:2019-12-25 16:00:51 【问题描述】:

问题是我总是收到没有任何有效负载的 400 响应代码。 即使出现问题,graphql 也会使用代码 200 和带有错误块的有效负载。事实上,GraphiQl 工作正常,告诉我设置和架构是正确的。所以......我被困住了。也许,有什么想法,去哪里看?

我不认为它失败是因为 cors 本身。我的应用在DRF 下运行良好。我决定尝试新的技术并使用 GQL 覆盖应用程序。

我的起源:http://127.0.0.1:8080

这是我的 Apollo 客户端:

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
);

这是我的请求(通过状态来自表单的变量值):

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

我使用 react-apollo-hook 进行查询:

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

我的架构(根据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)

从 GraphiQL 处理这个查询会给我一个有效的响应。 GraphiQL 在浏览器的另一个选项卡上的 http://127.0.0.1:8000/graphql 上运行。

查询:

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

变量:

   "username": "qwerty", "password": "qwerty"

回复:


  "data": 
    "tokenAuth": 
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InF3ZXJ0eSIsImV4cCI6MTU2NjMwMTkwNiwib3JpZ0lhdCI6MTU2NjMwMTYwNn0.NzgecEfFcnsrudcgrlZyBCC1rutoVJFciUI-ugFq9Fg"
    

【问题讨论】:

【参考方案1】:

这样,问题就解决了。不要忘记,当您按下没有明确定义类型的按钮时,将使用“提交”类型。

<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>

当您按下提交类型的按钮时,会调用渲染并且响应尝试将内容分派到未安装的组件。但是,如果您的按钮类型为“按钮”,则请求可以正常工作。我希望我的折磨能节省别人的时间。

【讨论】:

以上是关于通过 CORS 的 GraphQL 请求的无效响应和通过使用 JWT 的 GraphiQL 处理身份验证的有效响应的主要内容,如果未能解决你的问题,请参考以下文章

Apollo graphQL 客户端中的 CORS 异常“Access-Control-Allow-Headers 在预检响应中不允许请求标头字段内容类型”

CORS 问题:预检响应具有无效的 HTTP 状态代码 403

CORS 问题? - 预检响应包含无效的 HTTP 状态代码 405

Yii2 和 reactjs CORS 过滤器给出错误:预检响应具有无效的 HTTP 状态代码 401

即使服务器返回适当的响应标头,Firefox 也不允许 CORS 请求

已启用 CORS,但在 POST JSON 时,预检响应的 HTTP 状态代码 404 无效