首页 > 解决方案 > Larave CSRF 保护不起作用(当用户返回上一页时它不会禁止提交)

问题描述

我有一个我正在使用 ajax 提交的表单。当我提交并转到消息页面以进行成功操作时,如果用户返回到上一页并提交表单而不更改它(或者即使它更改),CSRF 保护不会拒绝重新加载和提交,它会在我的传输页面中做到这一点- 在这种情况下,一次提交在数据库中记录了 2 次或 3 次或更多。我认为这是一个 CSRF 问题,但不知道要解决它,也不知道是什么问题。我正在使用 ajaxsetup 验证 CSRF-TOKEN,如下所示:

  $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

更新

我的请求代码:

  public function post(TransfersClientForm $request)
    {

        $inputs = $request->validated();

        $currency = Wallet::find($inputs['origin'])->currency_id;

        $main_wallet = MainWallet::query()->where(['currency_id' => $currency])->first();
        $currency_symbol = Currency::find($inputs['origin'])->symbol;
        $key_min = 'transfer_min_' . $currency_symbol;
        $key_max = 'transfer_max_' . $currency_symbol;
        $limitation_max = Limitation::where(['key' => $key_max])->first()->value;
        $limitation_min = Limitation::where(['key' => $key_min])->first()->value;
        if ($inputs['amount'] < $limitation_min) {
            return response()->json(['error' => __('Minimum allowed transfer amount') . ': ' . $limitation_min . ' ' . __($currency_symbol)], 403);

        }
        if ($inputs['amount'] > $limitation_max) {
            return response()->json(['error' => __('Maximum allowed transfer amount') . ': ' . $limitation_max . ' ' . __($currency_symbol)], 403);

        }
        if ($inputs['type'] != 2 && $inputs['transfer_date'])
            return response()->json(
                [
                    'error' => __('You only can set time through timeend transger type!')
                ]
                , 403);
        /* @var $origin_wallet Wallet */
        $origin_wallet = \Auth::user()->wallets()->where(['currency_id' => $inputs['origin']])->first();
        $destination_wallet = Wallet::query()->where(['account_number' => $inputs['destination']])->first();

        if ($origin_wallet->currency_id != $destination_wallet->currency_id)
            return response()->json(['error' => __('Origin and destination wallet currencies are not the same')], 403);
        $value = [];
        foreach (Exchange::query()->where(['origin' => Currency::query()->find($inputs['origin'])->symbol])->get() as $key => $item) {
            $value[$item->destination] = $item->value;
        }
        switch (Currency::query()->find($inputs['origin'])->symbol) {
            case 'euro':
            case 'dollar':
                $wage = Wage::query()->where(['key' => 'transfer_dollar'])->first()->value;
                break;
            case 'toman':
                $wage = Wage::query()->where(['key' => 'transfer_toman'])->first()->value;
                break;
            case 'bitcoin':
                $wage = Wage::query()->where(['key' => 'transfer_bitcoin'])->first()->value;
                break;
        }
        $origin_balance = $origin_wallet->balance;
        $origin_total = $origin_wallet->total;
        $origin_balance -= $inputs['amount'];
        $origin_total -= $inputs['amount'];
        $transaction = new Transfer();
        $transaction->currency_id = $origin_wallet->currency_id;
        $transaction->amount = $inputs['amount'];
        $transaction->value = $value;
        $transaction->description = $inputs['description'];
        $transaction->unique_id = Str::random(16);
        $transaction->status = 0;
        $transaction->wage = $wage;
        $transaction->type = $inputs['type'];
        $transaction->origin_wallet_id = $origin_wallet->id;
        $transaction->destination_wallet_id = $destination_wallet->id;
        if ($origin_balance - $wage < 0)
            return response()->json(['error' => __('Not enough money')], 403);
        if ($inputs['type'] == 1) {
            $origin_wallet->update(['balance' => $origin_balance - $wage, 'total' => $origin_total - $wage]);
            $destination_balance = $destination_wallet->balance;
            $destination_total = $destination_wallet->total;
            $destination_balance += $inputs['amount'];
            $destination_total += $inputs['amount'];
            $destination_wallet->update(['balance' => $destination_balance, 'total' => $destination_total]);
            $transaction->status = 1;
            $transaction->transfer_date = Carbon::now();
            $transaction->save();
        }
        if ($inputs['type'] == 2) {
            $origin_balance = $origin_wallet->balance;
            $origin_balance -= $inputs['amount'];
            $origin_total = $origin_wallet->total;
            $origin_total -= $wage;
            $origin_hold = $origin_wallet->hold + $inputs['amount'];
            $origin_wallet->update(['balance' => $origin_balance - $wage, 'hold' => $origin_hold, 'total' => $origin_total]);
            $destination_balance = $destination_wallet->total;
            $destination_balance += $inputs['amount'];
            $destination_hold = $destination_wallet->hold + $inputs['amount'];
            $destination_wallet->update(['total' => $destination_balance, 'hold' => $destination_hold]);
            $path = '';
            if ($request->hasFile('file_image'))
                $path = $this->storeFile($request->file('file_image'));
            $transaction->src = $path;
            if (\Auth::user()->userInformation->national_phone_number_code == "+98") {
                $now = Carbon::createFromDate(Jalalian::now()->getYear(), Jalalian::now()->getMonth(), Jalalian::now()->getDay(), null);
                $transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'fa', 'Asia/Tehran');
                $transaction->time_end_deadline = $now->diffInDays($transfer_date);
                $transaction->transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'fa', 'Asia/Tehran');
            } else {
                $now = Carbon::now();
                $transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'en', null);
                $transaction->time_end_deadline = $now->diffInDays($transfer_date);
                $transaction->transfer_date = Carbon::parseFromLocale($inputs['transfer_date'], 'fa', 'Asia/Tehran');
            }
            $transaction->status = 1;
            $transaction->save();

        }
        if ($inputs['type'] == 3) {
            $origin_balance = $origin_wallet->balance;
            $origin_balance -= $inputs['amount'];
            $origin_total = $origin_wallet->total;
            $origin_total -= $inputs['amount'];
            $origin_wallet->update(['balance' => $origin_balance - $wage, 'total' => $origin_total - $wage]);
            $destination_balance = $destination_wallet->balance;
            $destination_balance += $inputs['amount'];
            $destination_total = $destination_wallet->total;
            $destination_total += $inputs['amount'];
            $destination_wallet->update(['total' => $destination_total, 'balance' => $destination_balance]);
            $path = '';
            if ($request->hasFile('file_image'))
                $path = $this->storeFile($request->file('file_image'));
            $transaction->src = $path;
            $transaction->time_end_deadline = 60;
            if (\Auth::user()->userInformation->national_phone_number_code == "+98")
                $transaction->transfer_date = Jalalian::now()->addMonths(2);
            else
                $transaction->transfer_date = Carbon::now()->addMonths(2);
            $transaction->status = 1;
            $transaction->save();

        }
        $history = new History();
        if ($transaction->status) {
            $currency = Wallet::find($inputs['origin'])->currency_id;
            $main_wallet = MainWallet::query()->where(['currency_id' => $currency])->first();
            $main_wallet->update(['balance' => $main_wallet->balance + $wage, 'total' => $main_wallet->total + $wage]);
            $history->action = 'successful transaction';
            $history->user_id = \Auth::id();
            $history->content = $inputs['amount'] . " "
                . Currency::query()->find($origin_wallet->currency_id)->symbol .
                " has been transfered to" . $destination_wallet->user->userInformation->first_name .
                " " . $destination_wallet->user->userInformation->last_name . "[" . $transaction->transfer_id . "]";
            $history->save();
            $transfer = [];
            $transfer['transfer'] = $transaction;
            $transfer['origin'] = $origin_wallet->account_number;
            $transfer['origin_info'] = ['user' => $origin_wallet->user, 'info' => $origin_wallet->user->userInformation];
            $transfer['destination_info'] = ['user' => $destination_wallet->user, 'info' => $origin_wallet->user->userInformation];
            $transfer['destination'] = $destination_wallet->account_number;
            $transfer['currency'] = $origin_wallet->currency->symbol;

            return redirect()->route('client.message')
                ->with('transfer_success', __('The transfer done successfully'))
                ->with('transfer_receipt', $transfer)->ajax();
        } else {
            $history->action = 'failed transaction';
            $history->user_id = \Auth::id();
            $history->content = "The transaction failed [" . $transaction->transfer_id . "]";
            $history->save();
            return response()->json(['error' => __('The transfer failed')], 403);
        }
    }

标签: laravelformscsrf

解决方案


推荐阅读