Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Как подружить капчу Yandex API и AJAX

Anna | 31.05.2014 | нет комментариев

Здравствуйте, уважаемые сотрудники. Споры о том, необходима ли так называемая «капча», приносит ли она реальную пользу в деле борьбы со злыми роботами либо только вредит «юзабилити» плана давным-давно утихли, и всякий, кто так либо напротив интересовался этим вопросом сделал для себя соответствующие итоги.

Тем не менее, столкнувшись с необходимостью установить капчу в форму авторизации для очередного плана, а так же позже нескольких часов возни с сервисом reCaptcha, тот, что генерирует на странице тоннымусорного кода, я так и не нашёл готового решения, которое бы устроило меня на сто процентов. Ну что же, если хочешь что-то сделать — сделай это сам.

В данной статье речь пойдёт о перевоплощении простого и комфортного API Яндекс — Чистый Веб в полновесную, современную и функциональную капчу. А раз уж мы заговорили о модуле авторизации, то думаю, что целесообразно будет показать — как наша новая капча работает в связке с модулем.

Выходит, нам потребуется:
API Яндекс — Чистый Веб.

Думаю что любителям нативного js огромнее ничего и не потребоваться, я же применял библиотеку jQuery

Первым делом обратимся к Yandex API, чай сперва нам необходимо получить желанную капчу. Почитав документацию пишем класс, тот, что собственно её и отдаёт:

class_yandex_capcha.php

class yandexCaptcha {
    static function get() {
        $lang = $_SESSION['lang'];
        if ($lang == "ru") {
            $type = "std";
        }
        else {
            $type = "estd";
        }
        $key = "Ваш API Ключ";
        $xmlResponse = file_get_contents("http://cleanweb-api.yandex.ru/1.0/get-captcha?key=".$key."&type=".$type);
        $xml = simplexml_load_string($xmlResponse);
        return $xml->url;
    }
}

Всё предельно легко — отправляем GET запрос с параметрами:
$key — Яндекс API Ключ, Получить дозволено здесь
$type — тип капчи, которую хотим получить, значения, принимаемые переменной всецело описаны в документации Яндекса.

В моём случае сайт поддерживает несколько языков — следственно в зависимости от языка выбираем: std — цифры и логотип Яндекса на русском, либо estd — тоже цифры, но с логотипом на английском.

Способ yandexCaptcha::get() сейчас возвращает адрес изображения — это и есть наша капча.
Помимо «url картинки капчи» xml запрос способа возвращает ещё один параметр — captcha, но есть крошечная хитрость вследствие которой
параметр captcha дозволено не беречь, скажем в сессии. Его вообще дозволено не беречь, отчего — объясню немножко дальше.

Когда наш класс готов — встраиваем его в модель страницы авторизации на сайте:

model_closed.php

class model_closed extends model {
        function get_data() {
            $root = $_SERVER['DOCUMENT_ROOT'];
            $dataArray['language'] = parse_ini_file($root."/app/languages/".Route::$lang."_closed.ini");
            $dataArray['base_href'] = $_SERVER['HTTP_HOST'];
            require_once($root."/app/core/class/class_yandex_capcha.php");
            $dataArray['capcha_url'] = yandexCaptcha::get();
            return $dataArray;
        }
    }     

Последние три строки способа get_data() отдают картинку капчи представлению:

А вот собственно и представление — closed_view.php

<div>
    <input type="text" value="<?php echo $data['language']['login']; ?>"><br>
    <input type="password" value="<?php echo $data['language']['passworld']; ?>">
    <div id="capcha" title="<?php echo $data['language']['reload_image']; ?>">
        <img src="" alt="<?php echo $data['language']['capcha']; ?>">
    </div>
    <input type="text" value="<?php echo $data['language']['capcha']; ?>">
    <div><div><?php echo $data['language']['loginBotton']; ?></div></div>
    <div></div>
</div>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/closed.js"></script>
<script type="text/javascript" src="/js/login.js"></script>

Как видно из представления — в html коде нет тегов form, а это значит, что скорее каждого для авторизации мы будем применять AJAX.

В представлении у нас 3 поля: логин, пароль и поле для ввода капчи, сама картинка капчи и кнопка отправить.

Отправлять форму, как теснее было сказано ранее, мы будем с поддержкой AJAX запроса в login.js

Много кода, но именно здесь – каждая суть

$(document).ready(function(){
    var capchaStartText = $(".capchaInput").val();
    var passworldStartText = $(".passworldInput").val();
    function login() {
        var login = $(".loginInput"), passworld = $(".passworldInput"), capcha = $(".capchaInput"), buttontext = $(".loginBottonInner").html(), captchasrc = $(".yandexCapchaImage").attr("src");
        var pos = captchasrc.indexOf("=");
        var key = captchasrc.substr(pos 1);
        $.ajax({
            type: "POST",
            url: "/app/modules/module_login.php",
            dataType: "json",
            data: {login:login.val(), passworld:passworld.val(), captchaCode:key, captchaValue:capcha.val()},
            beforeSend: function(){
                $(".loginBottonInner").html("...");
            }
        }).done(function(data){
            if (data.captcha == 1 && data.login == 1) {
                location.reload();
            }
            if (data.login == 0) {
                capchaRenew();
                $(".loginBottonInner").html(buttontext);
                login.focus();
                login.select();
                passworld.val(passworldStartText);
                capcha.val(capchaStartText);
                $(".loginError").html(data.login_error);
            }
            if (data.captcha == 0 && data.login == 1) {
                capchaRenew();
                $(".loginBottonInner").html(buttontext);
                capcha.val(capchaStartText);
                capcha.focus();
                $(".loginError").html(data.captcha_error);
            }
        });
    }
    function capchaRenew() {
        $.ajax({
            type: "POST",
            data: {check:"ok"},
            url: "/app/modules/module_capcha_renew.php"
        }).done(function(html) {
            $(".yandexCapchaImage").attr("src",html);
            console.log(html);
        });
    }
    $("#capcha").click(function(){
        capchaRenew();
        $(".capchaInput").focus();
    });
    $(".loginBottonInner").click(function() {
        login();
    });
    $(window).keydown(function(eventObject){
        if ($(".closedLoginForm input").is(":focus") == true) {
            if (eventObject.which == 13) {
                login();
            }
        }
    });
});

Сейчас нам необходимо проверить капчу.
Для этого из полей нашей формы по клику на кнопку «отправить» либо по кнопке Enter (любим пользователей), хватаем все данные — логин, пароль, комплект символов введённый пользователем в поле для ввода капчи, и ещё один параметр, о котором я писал выше — тот самый параметр captcha (смотри изложение способа yandexCaptcha::get()).
Дело в том, что данный параметр — ключевой для проверки правильности ввода капчи пользователемпервоначально присутствует на странице как часть URL картинки капчи. Её отдаёт нам Яндекс всё в том же способе yandexCaptcha::get(). Нам остаётся только «вычленить» параметр captcha из url адреса изображения, что мы и делаем.

Файл module_login.php которому мы передаём данные с поддержкой AJAX запроса, создаёт экземпляркласса Login — основного класса используемого нами для авторизации пользователей на сайте, вызывает способ siteLogin() тот, что возвращает данные о итоге авторизации, проверив перед этим правильность комбинации логин-пароль и, что нас волнует огромнее каждого — правильность ввода капчи.

    echo Login::siteLogin($login, $passworld, $captchaCode, $captchaValue);

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB