Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [cURL] formularz i ukryty token
Forum PHP.pl > Forum > PHP
magu112
Witam,
Chcę wysłać formularz lecz posiada on ukryty token który po odświeżeniu strony się zmienia a trzeba go też wysłać smile.gif

Tak wygląda token (przykład):
  1. <input name="thxytbwh" type="hidden" value="97a74bf0189ca6444e4ecbc1e8825da2" />

po odświeżeniu strony zmienia się wartość 'name', value jest stały bo to hash

i mam funkcję która by pobrała ten token, tylko jak go pobrać i wysłać bez przeładowania strony?
  1. preg_match("|name=\"(.+?)\".+ value=\"97a74bf0189ca6444e4ecbc1e8825da2\"|", $return, $name_login_hash);


mam coś takiego, z tym że strona się przeładowuje i token się zmienia ;| i nie wiem jak to obejść
  1. $send = new cURL();
  2. $send->get('http://' . $_POST['url'] . '/?action=forgo');
  3.  
  4. // pobieram hasha [jest zakodowany na początku strony w script]
  5. preg_match("|var login_hash = '(.+?)';|", $return, $login_hash);
  6.  
  7. // pobieram name hasha [token]
  8. preg_match("|name=\"(.+?)\".+ value=\"" . $login_hash[1] . "\"|", $return, $name_login_hash);
  9.  
  10. $send->post('http://' . $_POST['url'] . '/?action=forgo', 'subject='.$_POST['subject'].'&text='.$_POST['text'].'&' . $name_login_hash[1] .'='. $login_hash[1].'&send=send');



a przed tym mam jeszcze logowanie na stronie
  1. $login_site = new cURL();
  2. $login_site->get('http://' . $_POST['url']);
  3. $login_site->post('http://' . $_POST['url'], "login=" . $_POST['login'] . "&password=" . $_POST['password'] . "&submit=submit");



funkcja cURL
  1. class cURL {
  2. var $headers;
  3. var $user_agent;
  4. var $compression;
  5. var $cookie_file;
  6. var $proxy;
  7. function cURL($cookies=TRUE,$cookie='cookies.txt',$compression='gzip',$proxy='') {
  8. $this->headers[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
  9. $this->headers[] = 'Connection: Keep-Alive';
  10. $this->user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13';
  11. $this->compression=$compression;
  12. $this->proxy=$proxy;
  13. $this->cookies=$cookies;
  14. if ($this->cookies == TRUE) $this->cookie($cookie);
  15. }
  16. function cookie($cookie_file) {
  17. if (file_exists($cookie_file)) {
  18. $this->cookie_file=$cookie_file;
  19. } else {
  20. fopen($cookie_file,'w') or $this->error('The cookie file could not be opened. Make sure this directory has the correct permissions');
  21. $this->cookie_file=$cookie_file;
  22. fclose($this->cookie_file);
  23. }
  24. }
  25. function get($url) {
  26. $process = curl_init($url);
  27. curl_setopt($process, CURLOPT_HTTPHEADER, $this->headers);
  28. curl_setopt($process, CURLOPT_HEADER, 0);
  29. curl_setopt($process, CURLOPT_USERAGENT, $this->user_agent);
  30.  
  31. if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEFILE, $this->cookie_file);
  32. if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEJAR, $this->cookie_file);
  33. curl_setopt($process,CURLOPT_ENCODING , $this->compression);
  34. curl_setopt($process, CURLOPT_TIMEOUT, 30);
  35. if ($this->proxy) curl_setopt($process, CURLOPT_PROXY, $this->proxy);
  36. curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
  37. curl_setopt($process, CURLOPT_FOLLOWLOCATION, 1);
  38. $return = curl_exec($process);
  39. curl_close($process);
  40. return $return;
  41. }
  42. function post($url,$data) {
  43. $process = curl_init($url);
  44. curl_setopt($process, CURLOPT_HTTPHEADER, $this->headers);
  45. curl_setopt($process, CURLOPT_HEADER, 1);
  46. curl_setopt($process, CURLOPT_USERAGENT, $this->user_agent);
  47. if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEFILE, $this->cookie_file);
  48. if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEJAR, $this->cookie_file);
  49. curl_setopt($process, CURLOPT_ENCODING , $this->compression);
  50. curl_setopt($process, CURLOPT_TIMEOUT, 30);
  51. if ($this->proxy) curl_setopt($process, CURLOPT_PROXY, $this->proxy);
  52. curl_setopt($process, CURLOPT_POSTFIELDS, $data);
  53. curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
  54. curl_setopt($process, CURLOPT_FOLLOWLOCATION, 1);
  55. curl_setopt($process, CURLOPT_POST, 1);
  56. $return = curl_exec($process);
  57. curl_close($process);
  58. return $return;
  59.  
  60. }
  61. function error($error) {
  62. echo "<center><div style='width:500px;border: 3px solid #FFEEFF; padding: 3px; background-color: #FFDDFF;font-family: verdana; font-size: 10px'><b>cURL Error</b><br>$error</div></center>";
  63. }
  64. }
Quadina
Ale po co Ci przeładowywanie strony? Popatrz:
1. Przegladarka pobiera strone w tym dane z tokenem
2. Wpisujesz w przegladarce dane
3. Wysyłasz na zadany w action url wszyskie dane wraz z aktualnym tokenem

Gdzie tutaj potrzeba przeładowywania?
magu112
aha. no comments
--------
w skrócie, skrypt ma:
1. wejść na stronę formularza
2. pobrać token
2. wysłać formularz wraz z tokenem
// token za każdym odświeżeniem strony się zmienia

prosił bym o wypowiedzenie się kogoś doświadczonego
Quadina
Kolego, buduje boty od najmniej 5 lat, więc pozwolisz, że zignoruje Twój komentarz o doświadczeniu.

W twoim 2 (3?) punktowym opisie nawet sam podajesz informację, że nie pobierasz tokenu dwa razy. Mówiąc jak najbardziej łopatologicznie:
1. Dostajesz formularz od urzędnika z sygnaturą
2. Wypełniasz go swoim imieniem i nazwiskiem
3. Oddajesz mu formularz

Ponowie pytanie, gdzie tutaj podwójne proszenie urzędnika o formularz z sygnaturą - innymi słowy, gdzie potrzeba pobierania formularza dwa razy?

Z tego co widzę, nie masz pojęcia o działaniu formularzy stąd prawdopodobnie bierze się Twój problem. Otóż nasze przeglądarki nie pobierają formularzy więcej niż dwa razy bo wtedy nie miało by to większego sensu. Przy wysyłaniu danych z formularza wszystko pakuje się w jeden łańcuch danych i wysyła metodą odpowiednio GET lub POST do adresu zadanego w tagu form. Tam też ląduje token o którym wspominasz - nie ma zatem żadnej potrzeby pobierania tokena wielokrotnie.
amii
A nie możesz po prostu:
1. wczytać CURL-em strony bez przesyłania żadnych danych
2. pobrać ukryte i zmieniające się dane wyrażeniem regularnym
3. wczytać stronę CURL-em jeszcze raz i przesłać wszystkie kompletne dane
magu112
Cytat
A nie możesz po prostu:
1. wczytać CURL-em strony bez przesyłania żadnych danych
2. pobrać ukryte i zmieniające się dane wyrażeniem regularnym
3. wczytać stronę CURL-em jeszcze raz i przesłać wszystkie kompletne dane


właśnie o to chodzi że token jest już wtedy inny

żeby pobrać tokena muszę pobrać stronę łącząc się zalogowany przez curla, a żeby wysłać formularz z tokenem znów trzeba utworzyć nowe połączenie curl a wtedy token jest już inny
  1. $send = new cURL();
  2. // wczytuję stronę formularza aby pobrać tokena
  3. $send->get('http://' . $_POST['url'] . '/?action=forgo');
  4.  
  5. // pobieram hasha [jest zakodowany na początku strony w script]
  6. preg_match("|var login_hash = '(.+?)';|", $return, $login_hash);
  7.  
  8. // pobieram name hasha [token]
  9. preg_match("|name=\"(.+?)\".+ value=\"" . $login_hash[1] . "\"|", $return, $name_login_hash);
  10.  
  11. // wysyłam formularz wraz z pobranym tokenem
  12. $send->post('http://' . $_POST['url'] . '/?action=forgo', 'subject='.$_POST['subject'].'&text='.$_POST['text'].'&' . $name_login_hash[1] .'='. $login_hash[1].'&send=send');
Rid
Cytat(magu112 @ 19.12.2010, 16:47:25 ) *
aha. no comments
--------
w skrócie, skrypt ma:
1. wejść na stronę formularza
2. pobrać token
2. wysłać formularz wraz z tokenem
// token za każdym odświeżeniem strony się zmienia

prosił bym o wypowiedzenie się kogoś doświadczonego

Jedyna co mi przychodzi na myśl to AJAX
Quadina
Cytat
żeby pobrać tokena muszę pobrać stronę łącząc się zalogowany przez curla, a żeby wysłać formularz z tokenem znów trzeba utworzyć nowe połączenie curl a wtedy token jest już inny


Pytam się po raz trzeci. Po co pobierasz jeszcze raz formularz zamiast go wysłać? Innymi słowy, po co pobierasz formularz dwa razy? Przecież to jest zupełnie bezsensowne. Pomyśl jak robi to przeglądarka, pobiera dane wyświetla ci je, uzupełniasz i potem wysyłasz już przygotowany formularz... Nie wiem czemu uczepiłeś się tego podwójnego pobierania, a ja już nie wiem jak Ci to wytłumaczyć, że to nie jest problem z formularzem, ale z logiką tego zadania.

Cytat
Jedyna co mi przychodzi na myśl to AJAX

Nie wiem po co w tym wszystkim miałby być AJAX, do wypełnienia formularza po stronie przeglądarki? To zaraz Ci autor tematu napisze, że AJAX będzie chciał pobierać formularz dwa razy...

Jestem po raz kolejny zdruzgotany w tym tygodniu wiedzą teoretyczną i zadawaniem pytań o problemy, których nie ma. W razie co jestem dostępny na GG, mogę nawet pokazać jak zbudować takie wywołanie curla, tylko proszę nie mówcie mi, że nie da się obsłużyć tokena przez php, bo ta forma zabezpieczenie służy do anulowania używania funkcji "wstecz" w przeglądarce, a nie zabezpiecza przed botami.
Rid
Za pomocą Ajaxa ,może przesłać formularz bez przeładowania strony ,o to pytał autor strony.Metodą prób i błędów może coś wyjdzie.
Quadina
No swojej strony nie przeładujesz, ale załadujesz dwa razy AJAXem stronę zewnątrzną. Więc gdzie zysk?

Póki co autor musi się zastanowić co chce uzyskać, a nie co potrafi zrobić.
magu112
hmmm może prościej będzie na przykładzie captcha

bo captcha też za każdym razem jest inne (zmienia się z odświeżeniem strony)
a więc jak pobrać go do skryptu a potem wpisać/wysłać bez przeładowania strony, gdyż aby pobrać kod trzeba wywołać i zakończyć polecenie curl, a żeby go wpisać i wysłać znów trzeba nawiązać połączenie curl co wiąże się z ponownym wczytaniem strony co wiąże się z innym kodem...

wykonując taką czynność się nie da:
- rozpoczynam polecenie curl
- wchodzę na stronę
- wywołuję polecenie / zakańczam
- pobieram kod
- rozpoczynam polecenie curl
- wysyłam kod
- wywołuję polecenie / zakańczam curl
- kod jest zły / kod się zmienił
amii
A powinno być tak:
wykonując taką czynność się nie da:
- rozpoczynam polecenie curl
- jeśli potrzeba (są jakieś dane POST dynamicznie zmieniające się za każdym przeładowaniem) to pobieram te dane wyrażeniem regularnym z wyniku na poprzednim curl tutaj też obrabiam kod dla captacha czyli wyliczam pixelki i takie tam inne banalnie proste rzeczy winksmiley.jpg
- wykonuje jeszcze raz curl przesyłając wszystkie potrzebne dane

Gdzie tu widzisz problem ?

Tak jak mówiłem potrzebujesz najprawdopodobniej dwa razy wykonać CURL. Jak pisałem programy oparte o logowanie i automaty do postowania to czasami CURL trzeba było wykonać 3 razy.
1. Raz do zalogowania (autoryzacja)
2. Dwa do wczytania strony obsługującej pisanie posta (tu skanowałem wyniki wyrażeniem + obróbka danych)
3. Trzy przesłanie tych parametrów do strony odbierającej wyniki.
CuteOne
Magu:: skąd ten bulwers? Quadina dobrze prawi a ty go mięsem obrzucasz...

Łopatologicznie:
- wysyłasz żądanie na stronę np. http://www.gra.pl/formularz.php
- w ten sposób pobierasz token
- następnie wysyłasz dane na adres logowania np. http://www.gra.pl/loguj.php wraz z pobranymi wcześniej danymi

Innymi słowy nie wysyłaj danych do formularza tylko do pliku, który dane z formularza obrabia w tym wypadku loguj.php

ps. do jakiego pliku/ścieżki masz wysłać dane znajdziesz w polu action="" formularza
Quadina
@CuteOne Chwała Ci, Chwala, niech będzie chwała ;-)

Już myślałem, że na forum wszyscy wierzą, że żeby wysłać cokolwiek przez formularz to trzeba go najpierw 3 razy pobrać, potem upewnić się, że został pobrany (ewentualnie pobrać 4 razy) i potem go pobrać uzupełniając dane, żeby pobrać go jeszcze raz smile.gif
mmdo
Cytat(magu112 @ 19.12.2010, 16:47:25 ) *
w skrócie, skrypt ma:
1. wejść na stronę formularza
2. pobrać token
2. wysłać formularz wraz z tokenem
// token za każdym odświeżeniem strony się zmienia


Moje pytanie, po co chcesz przechować token? A jeżeli chcesz to np: baza(najbezpieczniej), sesja, cookie nawet plik na upartego.
CuteOne
Jemu chyba chodziło o pobranie tokena jako zmiennej, żeby potem mieć co wysyłać winksmiley.jpg chyba, że ma hobby i zbiera w bazie tokeny z różnych stron..
magu112
Już w ogóle nie kapuje działania tego curla ^^ siedzę dumam piszę ni działa ;]
za to napisałem na szybko tester i wrzuciłem go na demo stronę to testowania http://rebox.ugu.pl/
<-- rebox.ugu.pl
login login
hasło haslo
-->
jeżeli komuś uda się wysłać tamten formularz za pomocą curla i poda przykład jak to zrobił, będę bardzo wdzięczny ;]
thek
Przecież chłopaki mają racje jak byk! Pobierasz CURLem stronę, parsujesz ją pod kątem inputów z type="hidden" (DOM, simpleXML lub wyrażenia regularne) bo są takie 2. Pobierasz zarówno name jak i value i "przepychasz je" w CURLu dalej. Niepotrzebne jest wcale podwójne pobieranie strony. Tak jak piszą chłopaki:

1) pobierasz stronę rebox.ugu.pl/?action=frogo&i=wyslij
2) parsujesz to co dostajesz z CURLa by wyszukać inputy z polami typu hidden
3) ustawiasz w CURL dane POST na te znalezione przy parsowaniu
4) wysyłasz formularz na rebox.ugu.pl/?action=frogo&i=wyslij
5) cieszysz się biggrin.gif

Jeśli nadal nie rozumiesz, że to chłopaki mają racje to niestety ciężko widzę twoją przyszłość w programowaniu...
marcineck
Witam wszystkich i kłaniam się, gdyż jestem tu nowy,

A teraz do meritum.

Przeczytałem temat kilka razy i niestety mam podobny problem co kolega.
Mam formularz z ukrytym hashem, ktory to (dziad jeden) zmienia sie za kazdym przeladowaniem/pobraniem strony (hidden input).

CURL'a dopiero liznalem, wiec z gory dzieki za pomoc zaawansowanych w temacie.

Tak wyglada formularz:
  1. <form class="login" method="post" action="/login.php">
  2. <input name="hash" type="hidden" value="401704ef750f5f2e9fc84ed2c5db8292"><table>
  3. <tr>
  4. <td style="" align="right" width="150px">Username</td>
  5. <td><input type="text" name="user"></td>
  6. </tr>
  7. <tr>
  8.  
  9. <td style="" align="right" width="150px">Password</td>
  10. <td><input type="password" name="pass"></td>
  11. </tr>
  12. <tr>
  13. <td style="" align="right" width="150px"></td>
  14. <td><input type="submit" name="" value="Log in"></td>
  15. </tr>
  16. </form>



Login mam, haslo tez. Jesli pobieram strone CURLem, obrabiam ja i pobieram sobie token, ale... jak znowu wydam polecenie
  1. curl_setopt($ch, CURLOPT_URL, "http://costam.pl/login.php");

to token sie juz zmienia i ten pobrany jest do kitu.

Jeszcze raz - z gory dzieki za pomoc. Siedze, googluje, rwe wlosy z glowy i juz trace nadzieje, ze to logowanie z automatu jest mozliwe.
wNogachSpisz
Oszczędze Wam przechwałek, ile lat tworze boty smile.gif
Intryguje mnie, ze korzystacie z innych narzędzi, niż reszta świata...

Zamiast tego zamulonego CURL'a z API rodem z lat 90tych, używam PEAR:HTTP_Request.

zamiast wydłubywać inputy preg_matchem, używam PHP:DOM.

Radze zaczerpnąć z moich rad, opłaca się.

Pozdro600
marcineck
Dzięki za cynk.
Wygląda na to, że będę się musiał nauczyć nowych rzeczy, bo z HTML_REQUEST'em jeszcze nie miałem do czynienia.

A tak z czystej ciekawości: czy istnieje możliwość pobrania strony przez CURL, wycięcie HIDDEN INPUT, a następnie wysłanie strony (ale tej pobranej - nie pobieramy na nowy, tzn. bez reload'u ukrytego - wpieniającego mnie - tokena)?

Fifi209
Cytat(wNogachSpisz @ 5.03.2011, 23:30:09 ) *
zamiast wydłubywać inputy preg_matchem, używam PHP:DOM.

Jeżeli jesteś taki do przodu:
Fraza dla google: phpquery

;]
marcineck
Hej... to może spróbujmy inaczej.

Jako że nie mam już sił (od dwóch dni próbuje) męczyć się z tym formularzem - postawiłem tutaj demo:
http://www.e-care.pl/test/login.php

Komu uda się napisać skrypt logujący - stawiam piwo (ogłaszam wszem i wobec smile.gif.
Fifi209
Problem taki, że logowanie przez przeglądarkę nie działa. ;] Dopracuj skrypt to zaloguję się curlem.
cycofiasz
Za pewne wystarczy obsłużyć ciasteczka bo bez nich to za pewne token będzie się zmieniał w nieskończoność.

HTTP_Request nie jest standardowym rozszerzeniem w php więc jego użycie nie zawsze wchodzi w grę.
W swoich projektach korzystam z explode / preg_match ponieważ DOM był mało wydajny.
marcineck
Cytat(fifi209 @ 6.03.2011, 12:59:04 ) *
Problem taki, że logowanie przez przeglądarkę nie działa. ;] Dopracuj skrypt to zaloguję się curlem.



Oj. Bardzo przepraszam. To z pośpiechu smile.gif.
Formularz do testów już działa.
Fifi209
Gotowe.

  1. <?php
  2.  
  3. $ch = curl_init();
  4.  
  5. curl_setopt($ch, CURLOPT_URL, 'http://www.e-care.pl/test/login.php');
  6. curl_setopt($ch, CURLOPT_HEADER, true);
  7. curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt');
  8. curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt');
  9. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  10. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  11.  
  12. $site = curl_exec($ch);
  13.  
  14. preg_match('#([\w\d]{32,32})#', $site, $match);
  15.  
  16. curl_setopt($ch, CURLOPT_POST, true);
  17. curl_setopt($ch, CURLOPT_POSTFIELDS, 'login=test&haslo=test&hash='.$match[1]);
  18.  
  19. echo curl_exec($ch);
  20.  
  21. ?>


czekam na piwo, odezwij się na pw
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.