Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.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 ReCaptcha在iPhone上无法正常工作_Php_Iphone_Recaptcha - Fatal编程技术网

Php ReCaptcha在iPhone上无法正常工作

Php ReCaptcha在iPhone上无法正常工作,php,iphone,recaptcha,Php,Iphone,Recaptcha,我有一个网站与一个简单的联系方式。验证有点小,因为它不进入数据库;只是一封电子邮件。表格的工作原理如下: 共有5个字段,其中4个是必填字段。在4个字段有效之前,将禁用提交,然后您可以提交它。然后在服务器上再次验证所有内容,包括recaptcha(未经me客户端验证)。整个过程都是用ajax完成的,必须在服务器端通过多个测试,或者返回4**头,并调用失败回调处理程序 在桌面上,一切都像Chrome上的gangbusters(我没有尝试过其他浏览器,但我无法想象它们为什么会有所不同),但在iPhon

我有一个网站与一个简单的联系方式。验证有点小,因为它不进入数据库;只是一封电子邮件。表格的工作原理如下:

共有5个字段,其中4个是必填字段。在4个字段有效之前,将禁用提交,然后您可以提交它。然后在服务器上再次验证所有内容,包括recaptcha(未经me客户端验证)。整个过程都是用ajax完成的,必须在服务器端通过多个测试,或者返回4**头,并调用失败回调处理程序

在桌面上,一切都像Chrome上的gangbusters(我没有尝试过其他浏览器,但我无法想象它们为什么会有所不同),但在iPhone上,即使我没有选中测试框,reCaptcha也会进行验证

换句话说:我仍然必须正确填写这四个值才能提交,但是如果我没有选中reCaptcha复选框,请求仍然成功

如果有人认为这会有帮助,我可以发布一些代码,但问题似乎出在设备上,而不是代码上。有人对此有什么见解吗


注意:如果有帮助的话,服务器端是PHP/Apache


更新日期:2015年5月28日

我仍在调试,但似乎Mobile Safari忽略了我iPhone上的响应标题。当我将响应输出到页面时,我在桌面上得到的
(数据、状态、xhr)
是:

  • 数据
    :此时我的回答是错误或成功->
    错误

  • 状态
    错误

  • xhr
    {'error',400,'error'}

  • 关于移动safari:

  • 数据
    错误

  • 状态
    成功

  • xhr
    {'error',200,'success'}

  • 所以-它似乎只是忽略了我的响应标题。我试图显式地设置
    {“headers”:{“cache control”:“no cache”}
    ,但没有效果


    更新日期:2015年6月3日

    根据请求,这里是代码。这几乎肯定超出了您的需要。它也变得更迟钝,因为我已经作出了改变,试图修复它。还要注意的是,虽然看起来有些变量尚未定义,但它们(应该)已经在其他文件中定义

    客户端

    服务器:

    在客户端是否正确设置了“remoteIP”变量

    即使Ajax请求发送空值或假值,php脚本中的isset()函数也会返回true,从而错误地填充$remoteIp

    试着做:

    $remoteIp = $_SERVER['REMOTE_ADDR'];
    
    Ajax只是让浏览器执行请求,因此PHP可以完美地抓取用户的ip

    我敢肯定,如果您传递了错误的值,ReCaptcha将以某种方式陷入困境


    决不信任Ajax上的任何Javascript变量也更安全,因为这些变量也应被视为用户输入。

    验证码旨在防止恶意客户端(机器人),因此理论上如果客户端绕过验证码,这是服务器端的问题。(但是,如果客户端未能完成验证码,则可能是服务器端问题或客户端问题。)


    因此,问题一定出在服务器上。即使出于安全考虑,您也应该使用
    $\u服务器['REMOTE\u ADDR']
    ,而不是
    $\u POST['remoteIp']
    ,因为
    $\u POST['remoteIp']
    可能(被恶意客户端)伪造。事实上,
    $\u服务器['REMOTE\u ADDR']
    比客户端的
    $\u POST['remoteIp']
    可靠得多

    我在两三个月前编写了一个脚本,它仍然可以正常工作,请尝试以下方法:

    <?php
    $siteKey = ''; // Public Key
    $secret = ''; // Private Key
    /**
     * This is a PHP library that handles calling reCAPTCHA.
     *    - Documentation and latest version
     *          https://developers.google.com/recaptcha/docs/php
     *    - Get a reCAPTCHA API Key
     *          https://www.google.com/recaptcha/admin/create
     *    - Discussion group
     *          http://groups.google.com/group/recaptcha
     *
     * @copyright Copyright (c) 2014, Google Inc.
     * @link      http://www.google.com/recaptcha
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    /**
     * A ReCaptchaResponse is returned from checkAnswer().
     */
    class ReCaptchaResponse
    {
        public $success;
        public $errorCodes;
    }
    class ReCaptcha
    {
        private static $_signupUrl = "https://www.google.com/recaptcha/admin";
        private static $_siteVerifyUrl =
            "https://www.google.com/recaptcha/api/siteverify?";
        private $_secret;
        private static $_version = "php_1.0";
        /**
         * Constructor.
         *
         * @param string $secret shared secret between site and ReCAPTCHA server.
         */
        function ReCaptcha($secret)
        {
            if ($secret == null || $secret == "") {
                die("To use reCAPTCHA you must get an API key from <a href='"
                    . self::$_signupUrl . "'>" . self::$_signupUrl . "</a>");
            }
            $this->_secret=$secret;
        }
        /**
         * Encodes the given data into a query string format.
         *
         * @param array $data array of string elements to be encoded.
         *
         * @return string - encoded request.
         */
        private function _encodeQS($data)
        {
            $req = "";
            foreach ($data as $key => $value) {
                $req .= $key . '=' . urlencode(stripslashes($value)) . '&';
            }
            // Cut the last '&'
            $req=substr($req, 0, strlen($req)-1);
            return $req;
        }
        /**
         * Submits an HTTP GET to a reCAPTCHA server.
         *
         * @param string $path url path to recaptcha server.
         * @param array  $data array of parameters to be sent.
         *
         * @return array response
         */
        private function _submitHTTPGet($path, $data)
        {
            $req = $this->_encodeQS($data);
            $response = file_get_contents($path . $req);
            return $response;
        }
        /**
         * Calls the reCAPTCHA siteverify API to verify whether the user passes
         * CAPTCHA test.
         *
         * @param string $remoteIp   IP address of end user.
         * @param string $response   response string from recaptcha verification.
         *
         * @return ReCaptchaResponse
         */
        public function verifyResponse($remoteIp, $response)
        {
            // Discard empty solution submissions
            if ($response == null || strlen($response) == 0) {
                $recaptchaResponse = new ReCaptchaResponse();
                $recaptchaResponse->success = false;
                $recaptchaResponse->errorCodes = 'missing-input';
                return $recaptchaResponse;
            }
            $getResponse = $this->_submitHttpGet(
                self::$_siteVerifyUrl,
                array (
                    'secret' => $this->_secret,
                    'remoteip' => $remoteIp,
                    'v' => self::$_version,
                    'response' => $response
                )
            );
            $answers = json_decode($getResponse, true);
            $recaptchaResponse = new ReCaptchaResponse();
            if (trim($answers ['success']) == true) {
                $recaptchaResponse->success = true;
            } else {
                $recaptchaResponse->success = false;
                $recaptchaResponse->errorCodes = $answers [error-codes];
            }
            return $recaptchaResponse;
        }
    }
    
    $reCaptcha = new ReCaptcha($secret);
    
    if(isset($_POST["g-recaptcha-response"])) {
        $resp = $reCaptcha->verifyResponse(
            $_SERVER["REMOTE_ADDR"],
            $_POST["g-recaptcha-response"]
            );
        if ($resp != null && $resp->success) {echo "OK";}
        else {echo "CAPTCHA incorrect";}
        }
    ?>
    
    <html>
    
    <head>
    <title>Google reCAPTCHA</title>
    <script src="https://www.google.com/recaptcha/api.js"></script>
    </head>
    
    <body>
    <form action="reCAPTCHA.php" method="POST">
    <input type="submit" value="Submit">
    <div class="g-recaptcha" data-sitekey="<?php echo $siteKey; ?>"></div>
    </form>
    </body>
    
    </html>
    
    
    谷歌雷帕查
    像这个问题一样,最简单的解决方法是忽略自然头验证,在回调成功时,使用一些标志进行验证


    我见过一些这样的情况,但从来都不好闻。

    需要用于提交AJAX请求的Javascript来帮助您进行调试。您是否正在发布(请说“是”)而没有获得?如果您正在发布,但无法发布,请确保在请求中添加缓存破坏(不要只依赖于标题,因为有很多东西可以忽略标题)。但是发布JS,我们可以从中提供帮助。@user1167442是的,请提供一些代码:)这里会很有帮助。是的-添加了POST方法。代码。谢谢。暗中猜测-可能你的iPhone日期设置不正确。请提供一些服务器端代码(如你提到的PHP)?我100%确定存在服务器端问题。如果您试图仅从客户端修复此问题,恶意黑客仍然可以忽略验证码。根据我的代码,您无法看到它,但服务器上设置了
    remoteIP
    var。但是,在这两种情况下,为什么根据客户端浏览器会有所不同?如果是calc在客户端,另一个浏览器很可能会计算出不同的结果,将错误的IP发送回google。我认为javascript甚至无法访问remoteIP。不管怎样,这都是没有意义的。在这种情况下,它是在加载页面之前在服务器上计算的,并传递给javascript变量。看起来你说了两件事e、 你是说IOS上的Safari不支持captcha吗?另外,我不太明白第二部分如何适用于我的情况。@user1167442不。问题是Safari绕过了captcha。理论上,如果绕过了captcha,那一定是服务器端的问题。第二部分提出了一个可能的解决方案。谢谢你的通知接着,我改写了我的答案。
    $remoteIp = $_SERVER['REMOTE_ADDR'];
    
    <?php
    $siteKey = ''; // Public Key
    $secret = ''; // Private Key
    /**
     * This is a PHP library that handles calling reCAPTCHA.
     *    - Documentation and latest version
     *          https://developers.google.com/recaptcha/docs/php
     *    - Get a reCAPTCHA API Key
     *          https://www.google.com/recaptcha/admin/create
     *    - Discussion group
     *          http://groups.google.com/group/recaptcha
     *
     * @copyright Copyright (c) 2014, Google Inc.
     * @link      http://www.google.com/recaptcha
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    /**
     * A ReCaptchaResponse is returned from checkAnswer().
     */
    class ReCaptchaResponse
    {
        public $success;
        public $errorCodes;
    }
    class ReCaptcha
    {
        private static $_signupUrl = "https://www.google.com/recaptcha/admin";
        private static $_siteVerifyUrl =
            "https://www.google.com/recaptcha/api/siteverify?";
        private $_secret;
        private static $_version = "php_1.0";
        /**
         * Constructor.
         *
         * @param string $secret shared secret between site and ReCAPTCHA server.
         */
        function ReCaptcha($secret)
        {
            if ($secret == null || $secret == "") {
                die("To use reCAPTCHA you must get an API key from <a href='"
                    . self::$_signupUrl . "'>" . self::$_signupUrl . "</a>");
            }
            $this->_secret=$secret;
        }
        /**
         * Encodes the given data into a query string format.
         *
         * @param array $data array of string elements to be encoded.
         *
         * @return string - encoded request.
         */
        private function _encodeQS($data)
        {
            $req = "";
            foreach ($data as $key => $value) {
                $req .= $key . '=' . urlencode(stripslashes($value)) . '&';
            }
            // Cut the last '&'
            $req=substr($req, 0, strlen($req)-1);
            return $req;
        }
        /**
         * Submits an HTTP GET to a reCAPTCHA server.
         *
         * @param string $path url path to recaptcha server.
         * @param array  $data array of parameters to be sent.
         *
         * @return array response
         */
        private function _submitHTTPGet($path, $data)
        {
            $req = $this->_encodeQS($data);
            $response = file_get_contents($path . $req);
            return $response;
        }
        /**
         * Calls the reCAPTCHA siteverify API to verify whether the user passes
         * CAPTCHA test.
         *
         * @param string $remoteIp   IP address of end user.
         * @param string $response   response string from recaptcha verification.
         *
         * @return ReCaptchaResponse
         */
        public function verifyResponse($remoteIp, $response)
        {
            // Discard empty solution submissions
            if ($response == null || strlen($response) == 0) {
                $recaptchaResponse = new ReCaptchaResponse();
                $recaptchaResponse->success = false;
                $recaptchaResponse->errorCodes = 'missing-input';
                return $recaptchaResponse;
            }
            $getResponse = $this->_submitHttpGet(
                self::$_siteVerifyUrl,
                array (
                    'secret' => $this->_secret,
                    'remoteip' => $remoteIp,
                    'v' => self::$_version,
                    'response' => $response
                )
            );
            $answers = json_decode($getResponse, true);
            $recaptchaResponse = new ReCaptchaResponse();
            if (trim($answers ['success']) == true) {
                $recaptchaResponse->success = true;
            } else {
                $recaptchaResponse->success = false;
                $recaptchaResponse->errorCodes = $answers [error-codes];
            }
            return $recaptchaResponse;
        }
    }
    
    $reCaptcha = new ReCaptcha($secret);
    
    if(isset($_POST["g-recaptcha-response"])) {
        $resp = $reCaptcha->verifyResponse(
            $_SERVER["REMOTE_ADDR"],
            $_POST["g-recaptcha-response"]
            );
        if ($resp != null && $resp->success) {echo "OK";}
        else {echo "CAPTCHA incorrect";}
        }
    ?>
    
    <html>
    
    <head>
    <title>Google reCAPTCHA</title>
    <script src="https://www.google.com/recaptcha/api.js"></script>
    </head>
    
    <body>
    <form action="reCAPTCHA.php" method="POST">
    <input type="submit" value="Submit">
    <div class="g-recaptcha" data-sitekey="<?php echo $siteKey; ?>"></div>
    </form>
    </body>
    
    </html>