如何使用 SESSION 或 COOKIES (Opencart 3) 验证 PHP 中的 OTP

How to verify OTP in PHP with SESSION or COOKIES (Opencart 3)

我只是在 Opencart 中创建 OTP 验证系统。一切正常,但唯一的问题是数字未通过验证。我想我做错了什么。每次刷新页面时,OTP 也会更改。在 3-4 分钟的时间里,数字应该保持不变吗? 你们能告诉我哪里错了吗?

控制器代码如下:

<?php
class ControllerAccountOtpverify extends Controller {
private $error = array();

public function index() {
    if ($this->customer->getOtpverify() == 1) {
        $this->response->redirect($this->url->link('account/account', '', true));
    }

    $this->load->language('account/otp_verify');

    $this->document->setTitle($this->language->get('heading_title'));

    $this->load->model('account/customer');

    if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
        $this->model_account_customer->editOtpverify($this->request->post['otpverify']);

        $this->session->data['success'] = $this->language->get('text_success');

        $this->response->redirect($this->url->link('account/account', '', true));
    }

    $data['breadcrumbs'] = array();

    $data['breadcrumbs'][] = array(
        'text' => $this->language->get('text_home'),
        'href' => $this->url->link('common/home')
    );

    $data['breadcrumbs'][] = array(
        'text' => $this->language->get('text_account'),
        'href' => $this->url->link('account/account', '', true)
    );

    if (isset($this->error['otp'])) {
        $data['error_otp'] = $this->error['otp'];
    } else {
        $data['error_otp'] = '';
    }

    $data['otp'] = rand(1000, 9999);
    $_SESSION['otp'] = $data['otp'];

    $data['action'] = $this->url->link('account/otp_verify', '', true);

    $data['back'] = $this->url->link('account/login', '', true);


    $data['column_left'] = $this->load->controller('common/column_left');
    $data['column_right'] = $this->load->controller('common/column_right');
    $data['content_top'] = $this->load->controller('common/content_top');
    $data['content_bottom'] = $this->load->controller('common/content_bottom');
    $data['footer'] = $this->load->controller('common/footer');
    $data['header'] = $this->load->controller('common/header');

    $this->response->setOutput($this->load->view('account/otp_verify', $data));
}
private function validate() {
    if ((trim($this->request->post['otp'])) != $this->_SESSION['otp']) {
        $this->error['otp'] = $this->language->get('error_otp');
    }


    return !$this->error;
}
}

我对会话和 cookie 不熟悉,所以有人可以帮助我解决这个问题。 谢谢。

为此使用 Cookie

像这样

setcookie("postedArticle", true, time() + (60 * 4)); // 60 seconds ( 1 minute) * 4 = 4 minutes

检查使用

if(isset($_COOKIE['postedArticle']) && $_COOKIE['postedArticle'] == true)
{ 
    // IS SET and has a true value
}  

这些是从另一个答案中复制的。

下面是根据您的意见修改后的示例代码。不过我还没有测试过,所以请注意任何错误/警告:

<?php
class ControllerAccountVerify extends Controller {
    private $error = array();
    private $otp = array();

    public function index() {
        if ($this->customer->getPhoneverified() == 1) {
            $this->response->redirect($this->url->link('account/account', '', true));
        }

        $this->load->language('account/verify');

        $this->document->setTitle($this->language->get('heading_title'));

        $this->load->model('account/customer');

        if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
            $this->model_account_customer->editPhoneverified($this->request->post['phoneverified']);

            $this->session->data['success'] = $this->language->get('text_success');

            $this->response->redirect($this->url->link('account/account', '', true));
        }

        //$this->session->data['session_otp'] = '';

        if(isset($this->session->data['otp']) && $this->session->data['otp'] != '') {
            $this->otp = json_decode($this->session->data['otp']);

            // create a new OTP if it is expired
            if($this->otp->Expired) {
                $this->createOTP();
                $data['otp'] = $this->otp->Value;
            }
        } else {
            $this->createOTP();
            $data['otp'] = $this->otp->Value;
        }

        $data['debugTest'] = json_encode($this->session);

        $data['numberotp'] = $this->otp->Value;

        $data['breadcrumbs'] = array();

        $data['breadcrumbs'][] = array(
            'text' => $this->language->get('text_home'),
            'href' => $this->url->link('common/home')
        );

        $data['breadcrumbs'][] = array(
            'text' => $this->language->get('text_account'),
            'href' => $this->url->link('account/account', '', true)
        );

        if (isset($this->error['otp'])) {
            $data['error_otp'] = $this->error['otp'];
        } else {
            $data['error_otp'] = '';
        }

        $data['action'] = $this->url->link('account/verify', '', true);

        $data['back'] = $this->url->link('account/login', '', true);

        $data['column_left'] = $this->load->controller('common/column_left');
        $data['column_right'] = $this->load->controller('common/column_right');
        $data['content_top'] = $this->load->controller('common/content_top');
        $data['content_bottom'] = $this->load->controller('common/content_bottom');
        $data['footer'] = $this->load->controller('common/footer');
        $data['header'] = $this->load->controller('common/header');

        $this->response->setOutput($this->load->view('account/verify', $data));
    }

    private function validate() {
        if (!isset($this->request->post['otp'])) {
            $this->error['otp'] = $this->language->get('error_otp'); // No OTP posted to controller
        } else {
            $otp_value = $this->request->post['otp']; // set the posted value
        }

        // check that our session has a value
        if(!isset($this->session->data['otp'])) {
            $this->error['otp'] = $this->language->get('error_otp_session'); //  need to add an error message to handle if the session value is null
        } else {
            $this->otp = json_decode($this->session->data['otp']);
            // compare the posted otp to the value in session
            if(!$this->otp->Value == $otp_value) {
                $this->error['otp'] = $this->language->get('error_otp_invalid'); //  need to add an error message to handle if the otp does not match
            } else {
                // check if the otp has expired or not
                $elapsed_time = date_diff(date('Y-m-d H:i:s'),$session_otp['ExpireDateTime']);
                if(!$elapsed_time->mins < 5 ) {
                    $this->otp->Expired = true;
                    $this->error['otp'] = $this->language->get('error_otp_expired'); //  need to add an error message to handle if the otp expired
                }
            }
        }

        return !$this->error;
    }

    // reset the OTP property and update the session
    private function createOTP() {
        $this->otp = array(
            "Value"             => rand(1000, 9999),
            "ExpireDateTime"    => date('Y-m-d H:i:s', strtotime("+5 min")),
            "Expired"           => false
        );

        $this->session->data['otp'] = json_encode($this->otp);
    }
}