【问题标题】:Laravel 5.6 Signed URL not valid after user submit form用户提交表单后,Laravel 5.6 签名 URL 无效
【发布时间】:2020-02-28 18:56:39
【问题描述】:

在我的系统中,使用 Laravel 5.6,我们发送一封带有邀请链接(使用签名 URL)的电子邮件,用户单击该链接,填写表格并将其提交到服务器。至此,用户就被保存了。

签名的 URL 已包含电子邮件和 perfil_id(如 role_id)等数据,这些数据将在用户提交表单时分配。

我应该在什么时候使用$request->hasValidSignature() 方法? 因为如果我等待用户填写表单并提交,这里调用的方法会给hasValidSignature() 提供false。如果我在传递视图以供用户查看表单时进行验证,则验证将通过,但在发送表单之前,用户将能够篡改数据。

控制器内的签名 URL

$url = URL::temporarySignedRoute('completar', now()->addHours(5), [
            'email' => $request->get('email'),
            'perfil_id' => $request->get('perfil_id'),
            'empresa_id' => auth()->user()->empresa_id,
        ]);

    
    Mail::to($request->get('email'))->send(new UserRegistrationInvite($url));

用户在使用电子邮件上的链接后必须填写的视图内的表单

<form action="{{route("aceitar")}}" method="post">
            <input type="hidden" name="email" value="{{$request['email']}}">
            <input type="hidden" name="perfil_id" value="{{$request['perfil_id']}}">
            <input type="hidden" name="empresa_id" value="{{$request['empresa_id']}}">
            <input type="hidden" name="signature" value="{{$request['signature']}}">
            <br>
            <label for="name">Digite seu nome: </label>
            <input type="text" id="Nome" name="name" placeholder="Nome">
            <br>
            <label for="password">Digite sua senha: </label>
            <input type="password" name="password" id="password">
            <br>
            <label for="password_confirmation">confirme sua senha: </label>
            <input type="password" name="password_confirmation" id="password_confirmation">
            <hr>
            <button type="submit" id="convite">Enviar</button>
        </form>

用户提交表单时调用的函数。这里验证会失败

public function aceitar(Request $request) {
    // verifica se a signed URL é válida
    if (!$request->hasValidSignature()) {
        abort(response()->json('URL não válida - aceitar', 403));
    }

    // ao submeter o formulario anterior, faz validação
    $validator = Validator::make($request->all(), [
        'name' => 'required',
        'perfil_id' => 'required',
        'empresa_id' => 'required',
        'email' => 'required|email',
        'password' => 'required|confirmed'
    ]);

    // se validação falhar exibe erros na tela
    if ($validator->fails()) {
        return $validator->errors();
    } else {
        // se passar na validação usuário é criado com perfil e permissões ja relacionadas
        $usuario = User::create([
                                    'email' => $request->email,
                                    'name' => $request->name,
                                    'password' => bcrypt($request->password),
                                    'empresa_id' => $request->empresa_id,
                                ]);
        $usuario->perfil()->attach($request->perfil_id);

        return 'Usuário criado com sucesso';
    }

感谢您的宝贵时间。

【问题讨论】:

    标签: laravel url signed


    【解决方案1】:

    签名仅在用户访问的第一个 URL 上有效:'completar'。

    当他们发布表单时,相同的签名在“aceitar”路线上不再有效。

    您甚至可以在向他们展示表单之前验证签名并认为它是可信的。

    如果您想添加另一个验证步骤,您还可以为表单中的发布路由生成另一个临时签名 URL。

    【讨论】:

    • 感谢您的意见。如果我在用户填写表格之前进行验证,它将能够篡改我发送的“perfil_id”和“empresa_id”等信息,这正是我想要避免的。有什么建议吗?
    • 将签名值放入会话而不是表单中。
    • 我正在使用 API,所以我没有会话。最终将所有重要数据放在一个数组中,在返回的路上对其进行加密和解密。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-25
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    相关资源
    最近更新 更多