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

基于编辑权限控制Meteor应用中RecipeCard的编辑按钮显隐

解决Meteor食谱应用中编辑按钮的权限控制问题

核心思路

要实现仅食谱所有者可见编辑按钮,需要前端判断+后端校验结合:前端控制按钮显示,后端拦截非法操作,避免用户通过直接访问URL或API越权。

步骤1:确保食谱文档存储创建者ID

首先,你需要在添加食谱的逻辑中,给每个食谱文档添加owner字段,值为创建者的Meteor.userId()。示例方法代码:

Meteor.methods({
  'recipes.insert'(recipeData) {
    check(recipeData, {
      name: String,
      time: String,
      description: String,
      tags: [String],
      picture: String
    });

    // 未登录用户无法添加食谱
    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }

    // 插入时携带创建者ID
    Recipes.insert({
      ...recipeData,
      owner: this.userId,
      createdAt: new Date()
    });
  }
});

步骤2:修改RecipeCard组件控制按钮显示

在React组件中,通过useTracker获取当前登录用户ID,对比食谱的owner字段,仅匹配时渲染编辑按钮:

import { useTracker } from 'meteor/react-meteor-data';
import { Col, Card, Badge, Link } from 'react-bootstrap';
import { HeartFill } from 'react-bootstrap-icons';

const RecipeCard = ({ recipe }) => {
  // 获取当前登录用户
  const currentUser = useTracker(() => Meteor.user());
  const currentUserId = currentUser?._id;

  return (
    <Col>
      <Card className="h-100">
        <Card.Header>
          <Card.Img src={recipe.picture} />
          <Card.Title><Link to={`/recipes/${recipe._id}`}>{recipe.name}</Link></Card.Title>
          <Card.Subtitle>{recipe.time}</Card.Subtitle>
          <HeartFill />
        </Card.Header>
        <Card.Body>
          <Card.Text>
            {recipe.description}
          </Card.Text>
          <h6>Tags</h6>
          <Card.Text>
            {recipe.tags.map((tag, idx) => <Badge key={`${tag}${idx}`} bg="secondary" className="mx-1">{tag}</Badge>)}
          </Card.Text>
          {/* 仅所有者可见编辑按钮 */}
          {currentUserId === recipe.owner && (
            <Link to={`/edit/${recipe._id}`}>Edit</Link>
          )}
        </Card.Body>
      </Card>
    </Col>
  );
};

步骤3:后端添加编辑权限校验

仅前端隐藏按钮不够,必须在编辑食谱的方法中校验权限,防止用户通过API越权修改:

Meteor.methods({
  'recipes.update'(recipeId, updateData) {
    check(recipeId, String);
    check(updateData, {
      name: String,
      time: String,
      description: String,
      tags: [String],
      picture: String
    });

    if (!this.userId) {
      throw new Meteor.Error('not-authorized', '请先登录');
    }

    // 校验当前用户是否为食谱所有者
    const recipe = Recipes.findOne(recipeId);
    if (recipe.owner !== this.userId) {
      throw new Meteor.Error('not-authorized', '你只能编辑自己的食谱');
    }

    Recipes.update(recipeId, { $set: updateData });
  }
});

步骤4:路由层面拦截非法访问

如果使用React Router,在编辑页面组件中添加校验,防止用户直接输入URL访问不属于自己的食谱编辑页:

import { useTracker } from 'meteor/react-meteor-data';
import { useParams, Navigate } from 'react-router-dom';

const EditRecipe = () => {
  const { recipeId } = useParams();
  const currentUser = useTracker(() => Meteor.user());
  const recipe = useTracker(() => Recipes.findOne(recipeId));

  // 未登录跳转到登录页
  if (!currentUser) {
    return <Navigate to="/login" />;
  }

  // 非所有者跳转到食谱详情页
  if (recipe?.owner !== currentUser._id) {
    return <Navigate to={`/recipes/${recipeId}`} />;
  }

  // 正常渲染编辑表单
  return (
    // 你的编辑表单代码
  );
};

内容的提问来源于stack exchange,提问作者Amanda Achiu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:14:58