Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何防止用户绕过必须遵循的步骤过程?_Php_Jquery - Fatal编程技术网

Php 如何防止用户绕过必须遵循的步骤过程?

Php 如何防止用户绕过必须遵循的步骤过程?,php,jquery,Php,Jquery,我有一个多表单向导,有几个必须完成的步骤,这个脚本的开发与普通脚本非常不同,我的脚本避免了用户填写的数据丢失,也避免了丢失用户的步骤 脚本的步骤保存在一个会话中,该会话避免返回到开头,始终保持在用户的当前步骤中 但我在采取步骤的过程中遇到了一个漏洞问题 如果恶意用户以以下方式更改URL的值: localhost/wizard/saveTemp.php?step=6 该用户可以根据您的意愿跳过这些步骤 示例用户在步骤1中,但我修改了url并自动跳转到步骤6 因此,我如何通过使用PHP添加一个增强

我有一个多表单向导,有几个必须完成的步骤,这个脚本的开发与普通脚本非常不同,我的脚本避免了用户填写的数据丢失,也避免了丢失用户的步骤

脚本的步骤保存在一个会话中,该会话避免返回到开头,始终保持在用户的当前步骤中

但我在采取步骤的过程中遇到了一个漏洞问题

如果恶意用户以以下方式更改URL的值:

localhost/wizard/saveTemp.php?step=6
该用户可以根据您的意愿跳过这些步骤

示例用户在步骤1中,但我修改了url并自动跳转到步骤6

因此,我如何通过使用PHP添加一个增强的控件来防止他们戏弄系统,用户不能从步骤1跳到步骤3或步骤6,而是必须继续执行步骤1、2、3、4、5、6等的顺序

我的脚本向导

<?php
session_start();
if (isset($_GET['p'])) {
  session_destroy();
  session_start();
}
?>

<script>
var currentStep =  <?php echo $step ?>; // Variable indicating the current step, data selected with PHP sessions
var radio = <?php echo $radio ?>; //Value of the radius selected

function show_step(step) {
    var data = $("#form").serialize();
    var url = 'saveTemp.php?step=' + step;
    var valid = true;

    // [OPTIONAL] Validate only if you are going forward
    if (currentStep < step) {

      // We search all the fields within the current step.
      $('#step' + currentStep).find('input,textarea,select').each((idx, el) => {
        let $field = $(el);
        let $fieldCont = $field.closest('.form-group');

        // If the field is a checkbox or a radio and an option was not selected
        if (($field.prop('type') == 'checkbox' || $field.prop('type') == 'radio') &&
            !$fieldCont.find('input[name="'+$field.prop('name')+'"]:checked').length) {
          $fieldCont.addClass('error');
          valid = false;
        }
        // If the field is NOT a checkbox or a radio and is empty
        else if ($field.prop('type') != 'checkbox' && $field.prop('type') != 'radio' &&
          !$field.val()) {
          $fieldCont.addClass('error');
          valid = false;
        } else {
          $fieldCont.removeClass('error');
        }
      });
    }

    // If at least one field was not completed
    if (!valid) {
      return;
    }

    //
    $.ajax({
      type: "POST",
      url: url,
      data: data
    }).done(function(resp){
      $('#radio').val(resp.radio);

      if (step === 2) {
        var radio = parseInt(resp.radio);
        switch(radio) {
          case 1:
            urlform = './app/themes/pay_paypal.php'
            break;
          case 2:
            urlform = './app/themes/pay_paypal2.php'
            break;
          case 3:
            urlform = './app/themes/pay_paypal3.php'
            break;
          default:
            urlform = './app/themes/pay_paypal4.php'
            break;

        }

 $('#divPay').load(urlform,function(responseTxt, statusTxt, xhr){
          if(statusTxt === "success") {

            $('#step' + currentStep).css("display", "none");
            $('#step' + step).fadeIn("slow");
            currentStep = step;
          }
          if(statusTxt === "error") {
            //
          }
        });
      } else {

        $('#step' + currentStep).css("display", "none");
        $('#step' + step).fadeIn("slow");
        currentStep = step;
      }
    });
  };

  $(function() {
    show_step(currentStep);
    $('a.next').click(e => {
      e.preventDefault();
      show_step(currentStep + 1);
    });

    $('a.back').click(e => {
      e.preventDefault();
      show_step(currentStep - 1);
    });
  });
</script>

完成表单处理后,将步骤放入会话变量中。处理下一次提交时,请检查
$step
是否为下一步

$last_step = isset($_SESSION['step']) ? $_SESSION['step'] : 0;
if ($step > $last_step + 1) {
    die("You can't jump directly from step $last_step to $step");
}
在脚本结束时,验证所有信息后,将步骤保存在会话变量中:

$_SESSION['step'] = $step;
完整代码:

<?php
session_start();

$step =  isset($_GET['step']) ?  $_GET['step'] : 1;
$last_step = isset($_SESSION['data_form']['__step__']) ? $_SESSION['data_form']['__step__'] : 0;
if ($step > $last_step + 1) {
    die(json_encode(array('error' => 'Invalid step')));
}

// We save the form data in a session variable
$_SESSION['data_form'] = $_POST;
// we also add the step to the array, you can not use this name (__step__) as name in the form

$dataForm = (isset($_SESSION['data_form']) && is_array($_SESSION['data_form'])) ? $_SESSION['data_form'] :array();

$sStep = isset($dataForm['__step__']) ? $dataForm['__step__'] : 1;
$step = isset($step) ? $step : $sStep;

$radio   = isset($dataForm['radio']) ? $dataForm['radio'] : 1;

$_SESSION['data_form']['__step__'] = $step;

header('Content-Type: application/json');

$json =  array(
  'radio'     => $radio,
  'step'      => $step
);

echo json_encode($json);

我建议你不要这样做

我的意思是:我发现你也会验证用户输入,如果当前输入没有正确填写,就不允许用户进入下一步

我还发现,至少要在服务器端验证输入

默认情况下,没有任何子表单是有效的(没有任何用户输入),或者,如果是这样,您可以简单地添加一个隐藏的输入,并在某些事件(例如加载表单步骤)上自动填充它;您只需在每次请求任何步骤时重新验证整个表单(直到所需步骤)


例如,如果客户端请求第6步,但第5步未经验证,只需将http重定向头发送到第5步,或者发送一些最小的html错误,建议执行此操作,并提供手动执行此操作的链接。

使用POST方法没有帮助。用户可以使用开发人员工具更改带有步骤号的隐藏输入。@Barmar哇,我没想到会这样,谢谢您的澄清。Friend不起作用,请向我显示错误消息。会话变量设置正确吗?您是在设置了
$step=isset($\u GET['step'])
的代码之后执行此操作的吗?并且您执行了
$\u会话['step']=$step在脚本的末尾?问题是“必须继续执行步骤1、2、3、4、5、6等的顺序”。没有任何关于向后执行的内容。无论如何,如果您希望减少限制,您应该可以轻松修改上述代码中的逻辑。你真的需要我为你写整件事吗?你不是一个程序员,难道你不能从我写的东西中推断出来吗?
$_SESSION['step'] = $step;
<?php
session_start();

$step =  isset($_GET['step']) ?  $_GET['step'] : 1;
$last_step = isset($_SESSION['data_form']['__step__']) ? $_SESSION['data_form']['__step__'] : 0;
if ($step > $last_step + 1) {
    die(json_encode(array('error' => 'Invalid step')));
}

// We save the form data in a session variable
$_SESSION['data_form'] = $_POST;
// we also add the step to the array, you can not use this name (__step__) as name in the form

$dataForm = (isset($_SESSION['data_form']) && is_array($_SESSION['data_form'])) ? $_SESSION['data_form'] :array();

$sStep = isset($dataForm['__step__']) ? $dataForm['__step__'] : 1;
$step = isset($step) ? $step : $sStep;

$radio   = isset($dataForm['radio']) ? $dataForm['radio'] : 1;

$_SESSION['data_form']['__step__'] = $step;

header('Content-Type: application/json');

$json =  array(
  'radio'     => $radio,
  'step'      => $step
);

echo json_encode($json);