【问题标题】:custom validation in laravellaravel 中的自定义验证
【发布时间】:2016-10-29 23:06:33
【问题描述】:

我正在 Laravel 中集成亚马逊 MWS,到目前为止一切顺利,现在,在我的仪表板中,我创建了一个表单,用户可以在其中输入他的卖家 ID 和 Auth Token(由亚马逊提供)。我的代码是这样的

$store = StoreController::Find($id)->first();

$this->validate($request, [
'name'          => 'required|max:255',
'merchantId'    => 'required|max:255',
'authToken'     => 'required|max:255',
'marketplaceId' => 'required|max:255',
]);
 $mws    = new mwsController();
$result = $mws->checkCredentials($store);

if ($result) {
//credentials OK, Force Fill in database
//OK with it
// ALSO, I want to disable future Form Edits, any idea?
}else{
//return error on form, saying Merchant ID and Auth Token pair is invalid
//stuck at this point
//documentation doesnt help
}

1:问题 1: 正如我在代码中评论的那样,如何返回自定义错误

2:如果凭据正常,我想禁用表单中的未来编辑

说明

一旦我验证了凭据并更新了数据库,我希望该用户可以看到表单,但他无法编辑 Auth Token 、 Merchant ID 或表单中的任何其他字段。

非常感谢任何指导方针和帮助 谢谢

【问题讨论】:

    标签: php forms validation laravel


    【解决方案1】:

    我会将您的验证保留在 validate 方法中。这样,您的错误响应将开箱即用。这里解释了如何扩展验证器:https://laravel.com/docs/5.0/validation#custom-validation-rules

    它可能看起来像这样:

    Validator::extend('mwsToken', function($attribute, $value, $parameters)
    {
        // check if the token is valid an return result
    });
    

    然后你就可以在你的控制器中使用它了:

    $this->validate($request, [
    'name'          => 'required|max:255',
    'merchantId'    => 'required|max:255',
    'authToken'     => 'required|max:255|mwsToken',
    'marketplaceId' => 'required|max:255',
    ]);
    

    不再需要 if/else。您可以假设令牌在那里有效,因为验证已经通过。如果您正确设置验证器,错误报告将自动工作。


    至于第二个问题,不太清楚你的意思。如果您不想在某些情况下允许编辑,请不要呈现表单。可能是这样的(在您的控制器中):

    public function getEdit($id) {
       $model = Model::findOrFail($id);
    
       if ($model ->hasPropertyThatMeansNoEdit()) {
          abort(403);
       }
    
       // build and render edit form
    }
    

    不要忘记在您的 post 处理程序中执行类似的操作。始终假设用户是恶意的。不是因为没有表单,所以不能发出 POST 请求,即。通过操纵不同模型的请求。


    关于您的架构的最后一点说明。我注意到在你的 sn-p 中你直接调用你的控制器(StoreControllermwsController)。我认为你不应该那样做。控制器用于处理您的请求,仅此而已。如果其中有可重用的代码块,请考虑将该代码移至服务或命令,并从控制器内部调用该命令。它将使您的控制器更清洁(SRP),并使稍后在 ie 中重用这些命令变得更容易。 API 或队列作业或类似的东西。

    【讨论】:

    • 我喜欢您指出应用程序逻辑有点不稳定的方式。第一行 $store = StoreController::Find($id)->first(); 还包含控制器的模型逻辑。
    • 一遍又一遍地阅读你的答案以掌握最后一段。我相信我应该将它作为一项服务,但同一个控制器根据用户请求为用户获取数据,发送到模型并从模型并将其路由到视图,在这种情况下,您会建议什么?另外,请清除SRP,不完全了解
    • 让我们坚持这里的问题,在我的旁注中不再详细说明。请随时在CodeReview 上发布代码并将链接放在这里,我很乐意仔细查看并给您一些建议。 (顺便说一句,SRP 代表单一职责原则)
    • 至于编辑,如果您不希望用户再编辑凭据,您实际上不需要表单,是吗?只需向他们展示专用路线/视图的信息。而不是像我在回答中那样中止,您可以改为重定向到该专用视图。
    • 这是一种更简洁的方法,就像@JasonK 指出的那样,真的很高兴,两个答案都很棒,而且我仍然可以选择一个。不确定该选择谁:(
    【解决方案2】:

    docs 中指出了您第一个问题的答案:只需在响应中添加一个消息包即可。还可以查看 Laracast 上的初学者教程视频(由 Jeffrey Wade 制作),它们真的很有帮助。代码是:

    public function store(Request $request, $id)
    {
        // ...
    
        $this->validate($request, [
            'name'          => 'required|string|max:255',
            'merchantId'    => 'required|integer|max:255',
            'authToken'     => 'required|string|max:255',
            'marketplaceId' => 'required|integer|max:255',
        ]);
    
        $mws = new mwsController();
        if ($mws->checkCredentials($store)) {
            // Your code here
            return redirect('home')->with(['success' => 'Everything OK']); // Flash session
        }
    
        return redirect('home')->withErrors(['Merchant ID and Auth Token pair is invalid']); // Error bag
    }
    

    并显示:

    @if (session('success'))
        <div class="positive message">{{ session('success') }}</div>
    @endif
    
    @if (count($errors) > 0)
        <div class="negative message">{{ $errors->first() }}</div>
    @endif
    

    您的第二个问题很难回答,因为您没有提供任何代码或示例可供使用。也许我不明白这个问题,但我认为您正在寻找middleware

    编辑:要回答第二个问题,请在您的数据库表中添加一个名为“已验证”的列(默认 0)。如果凭据正常,请更新该列并将其设置为 1。在模板中使用该变量来操作表单字段,例如:

    <input type="text" name="merchantId" {{ $validated ? '' : 'disabled' }}/>
    

    【讨论】:

    • 你的方法更简单,但我在这里有一个 ajax 调用,所以重定向对我来说可能不是一个好的选择,+1 为你的帮助兄弟
    • 您编辑的答案将禁用一个字段(或应用时的所有字段),但仍然会无用地提交表单
    • 然后根本不向用户显示表单(甚至页面?)。一旦他通过身份验证,只需显示它的凭据。
    • 正在考虑不显示表单或禁用输入并提交按钮
    • 没关系。只要确保你也在服务器端检查它(!)。客户端仍然可以使用或不使用表单发出 POST 请求。另外对于 AJAX 调用,请查看我对这个问题的回答 stackoverflow.com/questions/37690068/…
    猜你喜欢
    • 2012-11-27
    • 2014-02-18
    • 2015-05-10
    • 1970-01-01
    • 2015-04-09
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    相关资源
    最近更新 更多