Данная задача возникла в связи с тем, что понадобилось зашифровать url. Решил её частично. То есть, для простых сайтов без горы скриптов – все будет работать идеально. С горой скриптов все будет работать почти идеально, если сервер сайта наш и там можно будет разрешить кроссдоменные запросы. Это почти – означает тонкую работу со скриптами. Вообще, как я понял, такие трюки запрещены в целях безопасности. Но задачу решать как-то надо было.
Способ №1 – независимый
Спрятать одну ссылку, при условии, что она нигде больше не светится на сайте можно следующим образом (получилось частично, в посте изложена идея подхода и некоторые трудности и их преодоление)…
-скачать HTML код страницы с сервера-источника
-подменить все относительные пути (href и src action) на абсолютные, указав сервер-источник
-получившийся HTML код выдать из под другого сервера, адрес которого можно шифровать как угодно.
-Создав страницу на другом сервере – можно ставить какие угодно ограничения – количество переходов, время работы ссылки на новую страницу и так далее.
Ограничение №1
Ограничение этого способа в том, что мы прячем только одну страницу. Если на ней есть ссылки, то сервер-источник будет обнаружен при переходе на неё. Но для задачи шифрования одной ссылки – этого вполне достаточно.
Ограничение №2
Ещё одно ограничение, если страница на скриптах фрэймворка, то такой подход тоже может не работать полностью. Тут нужно думать над каждым случаем отдельно.
Ограничение №3
Кросс-доменнные запросы как известно запрещены,
В частности, я работал с сайтом на Yii и при отправке Submit получил ошибку в отладчике браузера
1 |
XMLHttpRequest cannot load http://MY_URL. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access |
но если есть доступ на сервер, то с помщью php мы можем прописать в скрипте сервера, к которому обращаемся, строку в самом начале файла, разрешающую кроссдоменные запросы
1 |
<?php header('Access-Control-Allow-Origin: *'); ?> |
которая разрешит кроссдоменный запрос к данному домену. Можно, конечно и хром запускать с отключением режима безопасности
1 |
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security |
ШАГ № 1 – Загрузим произвольный сайт на своем сервере
Например, будем набирать в браузере
1 |
http://localhost:8080/?param1=Value1¶m2=Value2; |
а загрузится контент сайта
1 |
http://digital-flame.ru/ |
Это первое чего нужно добиться! Далее, уже можно поиграть с параметрами, зашифровать их, на сервере разместить ограничения – по времени использования и так далее.
Для простоты будем пользоваться стандартным веб-сервером в Delphi. Но такую же вещь можно проделать и с UniGUI сервером, скажем. Тут главное – идея. Если нужно решить задачу на профессиональном уровне, то можно все оформить в виде dll и прикрутить её к IIS.
Создадим веб-сервер
File > New > Other > Web Server Application
В результате у нас получатся 2 модуля
В WebModuleUnit
для начала выставим кодировку
1 2 3 4 5 6 7 |
procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin Response.ContentType := 'TEXT/HTML; CHARSET=UTF-8'; end; |
Далее запрограммируем основной обработчик
Идея в том, чтобы подменить все относительные пути на абсолютные
– в href,src и action
-если где-то ещё в HTML коде встретятся относительные пути, то можно подменить и их, по аналогии.
-ищем регулярками и вставляем в нужную позицию домен источника
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var OriginAdress: string; OriginHostMatch: TMatchCollection; OriginHost: string; OriginText: string; HrefMatches: TMatchCollection; i: Integer; Position: Integer; srcMatches: TMatchCollection; ActionMatches: TMatchCollection; begin //http://localhost:8080/?param1=Value1¶m2=Value2; //Download HTML content // if Request.MethodType=mtGet then begin if Request.QueryFields.Values['param1']='Value1' then begin OriginAdress:='http://digital-flame.ru/'; //----------- 1 Getting Origin Host OriginHostMatch:=TRegEx.Matches(OriginAdress,'^(https?:\/\/)?([\da-z\.-]+)'); OriginHost:=OriginHostMatch.Item[0].Value; // will give host http://system-roboxtest.ru //---------------------- 2 Adding host to src and to href OriginText:=IdHTTPWebModule.Get(OriginAdress); HrefMatches:=TRegEx.Matches(OriginText, 'href="[^"]*"'); if HrefMatches.Count<>0 then begin for i:=0 to HrefMatches.Count-1 do begin if not (HrefMatches[i].Value='href="/"') and not (HrefMatches[i].Value='href="#"') and not (Pos('http',HrefMatches[i].Value)<>0) then begin Position:=Pos(HrefMatches[i].Value,OriginText); OriginText.Insert(Position+5,OriginHost); end; end; end; srcMatches:=TRegEx.Matches(OriginText, 'src="[^"]*"'); if srcMatches.Count<>0 then begin for i:=0 to srcMatches.Count-1 do begin if not srcMatches[i].Value.Contains(OriginHost) then begin Position:=Pos(srcMatches[i].Value,OriginText); OriginText.Insert(Position+4,OriginHost); end; end; end; ActionMatches:=TRegEx.Matches(OriginText, 'action="[^"]*"'); if ActionMatches.Count<>0 then begin for i:=0 to ActionMatches.Count-1 do begin Position:=Pos(ActionMatches[i].Value,OriginText); OriginText.Insert(Position+7,OriginHost); end; end; Response.Content:=OriginText; end else begin Response.Content := '<html>' + '<head><title>Web Server Application</title></head>' + '<body>Web Server Application'+ '<br>'+ 'param1='+Request.QueryFields.Values['param1']+ '<br>'+ 'param2='+Request.QueryFields.Values['param2']+ '</body>' + '</html>'; end; end; end; |
Тестируем и смотрим, что у нас получилось…
Плюс этого способа в том, что код абсолютно независим.
ШАГ 2 Шифрование ссылки
Теперь, когда сайт загружен на наш сервер, и самое трудное позади, мы можем делать с ним всё, что угодно. С нашей ссылкой, я имею ввиду.
1 |
http://localhost:8080/?param1=Value1¶m2=Value2; |
Обратите внимание на эту конструкцию
1 |
if Request.QueryFields.Values['param1']='Value1' then |
По идее, мы можем делать здесь всё что угодно – ограничивать срок действия и выдавать в Response сообщение – “срок действия ссылки окончен”. Мы можем зашифровать параметрическую часть ссылки. Далее, действия зависят от задачи.
Чуть позже продолжу этот пост. Пока публикую как есть.
Способ №2 – через API сторонних серверов
Например, через NoBlockMe. Способ хорош – очень хорош, но ровно до того момента, пока работает данный сервис. В следующем посте рассмотрю способ работы через него.