简体   繁体   中英

Mutation failed due to permission errors - graphql and reactjs clienterror

All Post requests I try to perform on graphql using react doesn't work.I keep getting a 403 status error and the data do not get stored in the cms as it is supposed to. These codes were written to allow users make a comment on a blog post which doesn't work. I have the similar codes which performs the same tasks but they all do not work properly

First, lets start with the error I keep getting in the console after posting

ClientError: Mutation failed due to permission errors: {"response":{"errors":[{"message":"Mutation failed due to permission errors","extensions":{"code":"403","failedActions":[{"action":"create","model":"Comment","stage":"DRAFT"},{"action":"update","model":"Post","stage":"DRAFT"}]}}],"data":null,"extensions":{"requestId":"cl8a3xirno8yp0bt97dwj7e7m"},"status":403,"headers":{}},"request":{"query":"\n    mutation CreateComment($name: String!, $email: String!, $comment: String!, $slug: String){\n      createComment(data: {name: $name, email: $email, comment: $comment, post: { connect: {slug: $slug}}}){id}\n    }\n  ","variables":{"name":"miracle","email":"fav the miracle","comment":"I don not understand","slug":"bijofoods"}}}
    at /home/kimmoramicky/Desktop/fts_portfolio/node_modules/graphql-request/dist/index.js:359:31
    at step (/home/kimmoramicky/Desktop/fts_portfolio/node_modules/graphql-request/dist/index.js:63:23)
    at Object.next (/home/kimmoramicky/Desktop/fts_portfolio/node_modules/graphql-request/dist/index.js:44:53)
    at fulfilled (/home/kimmoramicky/Desktop/fts_portfolio/node_modules/graphql-request/dist/index.js:35:58)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  response: {
    errors: [ [Object] ],
    data: null,
    extensions: { requestId: 'cl8a3xirno8yp0bt97dwj7e7m' },
    status: 403,
    headers: Headers { [Symbol(map)]: [Object: null prototype] }
  },
  request: {
    query: '\n' +
      '    mutation CreateComment($name: String!, $email: String!, $comment: String!, $slug: String){\n' +
      '      createComment(data: {name: $name, email: $email, comment: $comment, post: { connect: {slug: $slug}}}){id}\n' +
      '    }\n' +
      '  ',
    variables: {
      name: 'miracle',
      email: 'fav the miracle',
      comment: 'I don not understand',
      slug: 'bijofoods'
    }
  }
}

The following codes are for the output

/services/index.js

import {request, gql} from 'graphql-request'

const graphqlAPI = process.env.NEXT_PUBLIC_GRAPHCMS_ENDPOINT

export const submitComment = async (obj) =>{
    const result = await fetch('/api/comments', {
        method: 'POST',
        headers:{
            'Content-type': 'application/json'
        },
        body: JSON.stringify(obj),
    })

    return result.json()
}

/api/blogComments.js

import { GraphQLClient, gql } from "graphql-request"

const graphqlAPI = process.env.NEXT_PUBLIC_GRAPHCMS_ENDPOINT
const graphcmsToken = process.env.GRAPHCMS_TOKEN

export default async function blogComments(req, res){
  const {name, email, slug, comment} = req.body

  const graphQLClient = new GraphQLClient(graphqlAPI, {
    headers: {
      authorization: `Bearer ${graphcmsToken}`
    }
  })

  const query = gql`
    mutation CreateBlogComment($name: String!, $email: String!, $comment: String!, $slug: String){
      createBlogComment(data: {name: $name, email: $email, comment: $comment, blogPost: { connect: {slug: $slug}}}){id}
    }
  `
  
  try{
    const result = await graphQLClient.request(query, req.body)
    return res.status(200).send(result)
  } catch (error) {
    console.log(error)
    return res.status(500).send(error)
  }

}

/components/BlogCommentsForm.jsx

import React, {useRef, useState, useEffect} from 'react'
import {submitBlogComment} from '../services'

const BlogCommentsForm = ({slug}) => {
  const [error, setError] = useState(false)
  const [localStorage, setLocalStorage] = useState(null)
  const [showSuccessMessage, setShowSuccessMessage] = useState(false)
  const commentEl = useRef()
  const nameEl = useRef()
  const emailEl = useRef()
  const storeDataEl = useRef()

  useEffect(()=>{
    nameEl.current.value = window.localStorage.getItem('name')
    emailEl.current.value = window.localStorage.getItem('email')
  }, [])

  const handleCommentSubmission = () => {
    setError(false)

    const {value: comment} = commentEl.current
    const {value: name} = nameEl.current
    const {value: email} = emailEl.current
    const {checked: storeData} = storeDataEl.current

    if(!comment || !name || !email ){
      setError(true)
      return
    }

    const commentObj = {name, email, comment, slug}

    if(storeData){
      window.localStorage.setItem('name', name)
      window.localStorage.setItem('email', email)
    } else {
      window.localStorage.removeItem('name', name)
      window.localStorage.removeItem('email', email)
    }

    submitBlogComment(commentObj)
      .then((res) =>{
        setShowSuccessMessage(true)
        setTimeout(()=>{
          setShowSuccessMessage(false)
        }, 3000)
      })
  }

  return (
    <div className="bg-white shadow-lg rounded-lg p-8 pb-12 mb-8">
      <h3 className="text-xl mb-8 font-semibold border-b pb-4">Leave a Comment</h3>
      <div className="grid grid-cols-1 gap-4 mb-4">
        <textarea 
          ref={commentEl} 
          name="comment" 
          // id="" cols="30" rows="10"
          placeholder="Comment"
          className="p-4 outline-none w-full rounded-lg focus:ring-2 focus:ring-gray-200 bg-gray-100 text-gray-700">
        </textarea>
      </div>
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-4">
        <input 
        type="text" 
        ref={nameEl}
        className ="py-2 px-4 outline-none w-full rounded-lg focus:ring-2 focus:ring-gray-200 bg-gray-100 text-gray-700"
        placeholder="Name"
        name="name"
      />
        <input 
        type="text" 
        ref={emailEl}
        className ="py-2 px-4 outline-none w-full rounded-lg focus:ring-2 focus:ring-gray-200 bg-gray-100 text-gray-700"
        placeholder="Email"
        name="email"
      />
      </div>
      <div className="grid grid-cols-1 gap-4 mb-4">
        <div>
          <input type="checkbox" ref={storeDataEl} id="storeData" name="storeData" value="true" />
          <label className="text-gray500 cursor-pointer ml-2" htmlFor="storeData">Save my e-mail and name for the next time I comment</label>
        </div>
      </div>
      {error && <p className="text-xs text-red-500">All fields are required.</p>}
      <div className="mt-8">
        <button 
          className="transition duration-500 ease inline-block bg-[#EF4036] text-lg rounded text-white px-8 py-2 cursor-pointer"
          type="button" 
          onClick={handleCommentSubmission}
          >Post Comment</button>
          {showSuccessMessage && <span className="text-sm float-right font-semibold mt-3 text-green-500">Comment submitted for review</span>}
      </div>
    </div>
  )
}

export default BlogCommentsForm

Pls I really appreciate your help, I have been stuck here for too long

I got the same error and resolved it by giving permission to the auth token I was using.

Visit your graphql project dashboard. Then

Project Settings > ACCESS > API Access > Endpoints

Update permissions of the Auth Token

The error appeared to me too and I solved it by giving permissions to the token.

Settings > ACCESS > API Access >

At the bottom there should be a section called

Permanent Auth Tokens

There I hit the three dots and I got the option to edit.

Where it says " Content API " look for the button where it says Add permission and I gave it all the permissions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM