Pull to refresh

«CAPTCHA: Прототип» или очередная попытка уйти от разгадывания капчи

Reading time 3 min
Views 8.3K
Наверно каждый веб-программист задумывался о том, как избавиться от назойливых картинок антиспама, которые по смыслу должны пресекать ботов-спамеров, а на деле отпугивают реальных посетителей. Работая над очередной поделкой на HTML5+JS+canvas, пришла идея нового прототипа защиты от ботов. Данная идея не что иное как очередная вариация самой капчи, но на этот раз без дурацких «угадываний» символов.





Как это работает?


Для того, чтобы пройти проверку анти-бота, пользователю предлагается кликнуть на кружок определенного цвета. Тут сразу можно добавить, что это всего лишь прототип, и выставляется на всеобщее обсуждение для того, чтобы хоть как-то сдвинуться с мертвой точки монополии капчи. Кружки рисуются на холсте (canvas). При этом в моем примере они рисуются прямо в JavaScript. В рабочем варианте предполагается рисовать их на стороне сервера, и на холст отрисовывать только готовую картинку.

Сам прототип целиком можно найти на гитхабе.

А тем временем я опишу основные методы, которые использовались для реализации:
1. Создадим некий массив цветов будущих кружочков.
this.colors = ["red", "green", "blue", "pink", "yellow", "orange", "violet"];

2. Генерируем сами кружочки.
generateObjects = function(g) {
    var used = [];
    var used_ = [];
    // перемешиваем цвета
    var colors = shuffle(self.colors);
    // выбираем случайное количество кружочков, но не менее трех 
    var howMuch = rand(3, colors.length);
    for (var i = 0; i < howMuch; i++) {
        var centerX = rand(10, self.width);
        var centerY = rand(10, self.height);
        var radius = rand(10, 15);
        g.beginPath();
        g.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
        g.fillStyle = colors[i];
        g.fill();
        g.lineWidth = 1;
        g.strokeStyle = colors[i];
        g.stroke();
        used.push(colors[i]);
        used_.push({
            x: centerX,
            y: centerY,
            // указываем радиус, он нам пригодится для определения пересечений
            r: radius
        });
    }
    // выбираем случайный кружок и делаем его ответом на капчу 
    var a = rand(0, howMuch - 1);
    self.active = used_[a];
    return used[a];
};

3. Для того, чтобы определить пересечение нажатия и кружочка, используем два метода.
mouseReleased = function(dim) {
    // координаты нам пришли из lib/captcha_listener.js
    dim.x = dim.x - $(self.canvas).offset().left;
    dim.y = dim.y - $(self.canvas).offset().top;
    // сначала проверяем, был ли совершен клик на саму "капчу"
    if (self.inBounds(dim)) {
        // выводим координаты нажатия
        $(".captchaResult").val(dim.x + ":" + dim.y);
        // ну и так как это POC, проверяем и уведомляем пользователя, попал он по правильному кружочку или нет
        if (self.inCircle(dim)) {
            alert("nice!");
        } else {
            alert("bot...");
        }
    }
};

Сама проверка inCircle()
inCircle = function(dim) {
    var a = self.active;
    // как и говорилось до этого, используем радиус для определения пересечений
    // NB! здесь по-хорошему должна использоваться формула окружности, я в свою очередь оставил вариант по проще
    var x0 = a.x - a.r;
    var x1 = a.x + a.r;
    var y0 = a.y - a.r;
    var y1 = a.y + a.r;
    if (x0 <= dim.x && dim.x <= x1 && y0 <= dim.y && dim.y <= y1) {
        return true;
    } else {
        return false;
    }
};


И собственно вот так выглядит наша свежеиспеченная капча:


К сожалению, такая капча будет проблемой не только для ботов, но и для людей не различающих цвета.

С радостью выслушаю предложения по поводу капчи. Смело делайте форки, если идея понравилась. Напомню, что это лишь прототип того, что можно сотворить из этой идеи.

UPD.: Уже после первых комментариев к статье, появилась идея добавить цветной шум к данной капче.
Tags:
Hubs:
-5
Comments 37
Comments Comments 37

Articles