Валидация клиентов по наличию JavaScript

Pavel Zhovner pavel на zhovner.com
Сб Сен 24 10:32:26 UTC 2011


Здравствйте.

 Задача пропускать к бекенду только клиентов с включенным javascript,
для этого на стороне клиента и сервера предполагается посчитать хеш на
основе ip клиента.
Для этого используется сторонний модуль ngx_http_set_hash  и
аналогичная функция на javascript которая результат вычислений
записывает в cookie.
Алгоритм работы страницы с javascript такой: посчитать хеш из адреса,
занести результат в cookie с названием sha1, обновить страницу.

Конфиг выглядит так:


  location / {
 	
         #Если нет cookie отправить на страницу с javascript
	
            if ( $cookie_sha1 = "" ){
	  rewrite ^ /no_cookie.html last;
                                             }

         # Генирация хеша из ip

            set_sha1          $sha1_hash          $remote_addr;
	set                   $twovars 	   $cookie_sha1:$sha1_hash";

        # Проверить правильность cookie sha1 в противном случаи
отправить на страницу с javascript
        # конструкция с двумя переменными в одной использована потому,
что в nginx нельзя сравнить переменную с переменной

           if ($twovars !~* "^(.*):\1$") {
	 rewrite ^ /bad_cookie.html last;
	    		              }
       # Иначе отправить запрос бекенду

           proxy_pass   http://backend;
                }

       # location ведущие на страницы с javascript. (Разделены на две
чтобы логировать оба события)

            location  /no_cookie.html {
	add_header Set-Cookie "addr=$remote_addr; path=/";
            root /page/javascript;
	internal;
            access_log /log/rewrite.log nocookie;					
		                       }

            location  /bad_cookie.html {
            add_header Set-Cookie "addr=$remote_addr; path=/";
            root /page/javascript;
	internal;
            access_log /log/rewrite.log badcookie;					
		                        }
	

Такая конструкция полностью работоспособна и свою задачу выполняет.
 Два отдельных локейшена no_cookie и bad_cookie созданы для того чтобы
логировать какой именно rewrite сработал, потому что access_log
помещенный перед действитем rewrite не записывает лог.
Покритикуйте пожалуйста такое решение и укажите на ошибки. Например
при срабатывании условия отсутвия куки (первый rewrite) будет ли
выполнено set_sha1, хотя по логике при срабатывании рерайта last будет
сразу выполнен выход из location /
Так же возможно ли организовать некое подобие white list чтобы не
считать хеш на каждый легитимный запрос, а после первого успешного
сравнения пропускать без проверки хеша? Например с помощью модуля
geoip.


Подробная информация о списке рассылки nginx-ru