You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Sanity CMS客户端提交数据遇403权限错误求助

Sanity CMS客户端提交数据出现403权限错误的解决方案

问题场景

使用Sanity CMS作为后端构建React应用,其他功能正常,但访客提交表单数据时触发403错误,报错提示Insufficient permissions; permission "create" required。

疑似出错的Footer组件代码

import React, { useState } from 'react';

import { images } from '../../constants';
import { AppWrap, MotionWrap } from '../../wrapper';
import { client } from '../../client';

import './Footer.scss';

const Footer = () => {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });

  const [isFormSubmitted, setIsFormSubmitted] = useState(false);
  const [loading, setLoading] = useState(false);

  const { name, email, message } = formData;


  const handleChangeInput = (event) => {
    const { name, value } = event.target;

    setFormData({ ...formData, [name] : value})
  }

  const handleSubmit = () => {
    setLoading(true);

    const contact = {
      _type: 'contact',
      name: name,
      email: email,
      message: message
    }

    client.create(contact)
      .then(() => {
        setLoading(false);
        setIsFormSubmitted(true);
      })
      .catch(err => console.log(err));
  }
  return (
    <>
      <h2 className="head-text">Take a coffee & chat with me...</h2>
      <div className="app__footer-cards">
        <div className="app__footer-card">
          <img src={images.email} alt="email" />
          <a href="mailto:ecommercedock@gmail.com" className="p-text">ecommercedock@gmail</a>
        </div>
        <div className="app__footer-card">
          <img src={images.mobile} alt="mobile" />
          <a href="tel: +256 750 242627" className="p-text">+256 750 242627</a>
        </div>
      </div>

      {!isFormSubmitted ?
        (<div className="app__footer-form app__flex">
          <div className="app__flex">
            <input className='p-tex' type="text" placeholder='Your Name' name='name' value={name} onChange={handleChangeInput} />
          </div>
          <div className="app__flex">
            <input className='p-tex' type="email" placeholder='Your Email' name='email' value={email} onChange={handleChangeInput} />
          </div>
          <div>
            <textarea
              className='p-text'
              placeholder='Your Message'
              name="message"
              value={message}
              onChange={handleChangeInput}
            />
          </div>
          <button type='button' className='p-text' onClick={handleSubmit}>{loading ? 'Sending' : 'Send Message'}</button>
        </div>)
        : (<div>
          <h3 className="head-text">Thank you for getting in touch with me....</h3>
        </div>)
      }
    </>
  )
}

export default AppWrap(
  MotionWrap(Footer, 'app__footer'),
  'contact',
  'app__whitebg'
)

客户端报错信息

{
  "error": {
    "description": "Mutation(s) failed with 1 error(s)",
    "items": [
      {
        "error": {
          "description": "Insufficient permissions; permission \"create\" required",
          "permission": "create",
          "type": "insufficientPermissionsError"
        },
        "index": 0
      }
    ],
    "type": "mutationError"
  }
}

错误状态码:403

问题原因及解决步骤

1. 核心原因:前端客户端使用只读令牌

Sanity默认生成的客户端令牌只有只读权限,仅能获取数据,无法执行创建/修改操作。直接在前端用该令牌调用client.create()必然触发403权限拦截。

2. 生产环境正确处理方式(令牌安全优先)

绝对不能将带写入权限的令牌直接暴露在前端代码中,会导致恶意用户盗用令牌篡改数据。正确流程:

  • 搭建后端服务(如Node.js/Express)
  • 在后端配置带写入权限的Sanity令牌,接收前端表单提交请求
  • 前端将表单数据发送到自有后端API,由后端调用Sanity接口完成数据创建

3. 本地临时调试方案(禁止用于生产)

若仅需本地测试,可临时配置写入令牌:

  • 登录Sanity管理后台,进入Settings > API > Tokens
  • 创建新令牌,勾选create等所需权限
  • 修改客户端初始化代码:
// client.js 文件
import { createClient } from '@sanity/client';

export const client = createClient({
  projectId: '你的项目ID',
  dataset: '你的数据集',
  apiVersion: '2022-10-26', // 与请求的API版本保持一致
  token: '你的写入权限令牌',
  useCdn: false, // 写入操作必须关闭CDN
});

4. 检查Sanity权限规则

确认项目权限规则允许创建contact类型文档:

  • 在Sanity Studio中,检查schemas/contact.js配置,或进入Settings > API > Permissions调整规则
  • 默认规则可能仅允许认证用户创建数据,需确保令牌对应账号有足够权限

额外小问题

代码中两个输入框的className写成了p-tex,应修正为p-text,避免样式异常。

内容的提问来源于stack exchange,提问作者coding beast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:15:56