我有一份调查表。每个问题都有3-4个预定义的答案作为单选按钮.单选按钮的值是数据库中答案的主键。
由于所有问题的答案都存储在一个表中,如果用户增加了值,ID可能仍然是一个有效的外键,但它不属于该问题。
确保单选按钮的值不被操纵的最佳实践是什么?
发布于 2017-11-13 11:59:21
确保无线电按钮的价值不被操纵。
你不能,这是错误的方法。始终假定客户端信息可以被操纵。
相反,验证向服务器发出的请求的业务逻辑。当服务器端代码接收到一组提交的问题和答案时,根据您拥有的数据验证所提交的数据是否有效。
这可以通过先查询数据库,执行验证逻辑,然后保存数据来完成。可以通过创建存储过程或其他数据库端逻辑来确保有效的数据,然后只与数据库交互一次。等。无论哪种方式,都要由您来定义和验证系统中列出的业务规则。
发布于 2017-11-13 13:01:06
在您的控制器中,您可以这样做:
# Get the ids of the answers that are valid for that question
$validAnswerIds = $Question->answers->pluck('id')->toArray();
# Validate that the answer given is in there
$rules = ['answer' => Rule::in( $validAnswerIds ) ];
$request->validate( $rules );发布于 2017-11-13 13:44:41
作为大卫已经提到,您需要验证您的业务逻辑。
像你说过一样,最“笨拙”的方法是在请求类中执行验证,并在需要时开发额外的验证器扩展。在控制器中添加验证逻辑(如艾琳提到 )根本不是一个好的实践,尽管它是有效的。
我想您有两个独立的模型:Question和Answer。此外,在他们之间建立了一个完整的1-N关系,即一个问题可以有许多答案,每个答案都属于一个问题:
class Question extends Model
{
public function answers()
{
return $this->hasMany(Answer::class);
}
}
class Answer extends Model
{
public function question()
{
return $this->belongsTo(Question::class);
}
}假设你也有一个SurveyController
class SurveyController extends Controller
{
public function store(CreateSurveyRequest $request)
{
// Request is validated by now and you can be sure that the
// answer belongs to the question. Go on and create/store
// the Survey entity.
}
}以及执行实际数据验证的请求类:
class CreateSurveyRequest extends FormRequest
{
public function rules()
{
// Assuming the request contains `answer_id` and `question_id` fields:
return [
'answer_id' => 'exists:answers,id,question_id,' . request('question_id'),
// e.g.
// 8 => 'exists:answers,id,question_id,10'
// Which loosly translates to "answer ID 8 should belong to question ID 10"
];
}
}这样的exists规则定义确保应答记录在questions表上有一个外键,因此它是对问题的有效答案。
重点是Laravel的exists规则支持附加条件。有趣的是,提交提案的那个人感觉和你在这里的需求完全一样。
https://stackoverflow.com/questions/47263762
复制相似问题