基于编辑权限控制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
相关产品推荐
相关产品推荐

