Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Analizujemy kod portalu dobreprogramy.pl — czyli jak działa system powiadomień

Ostatnim wpisem rozpoczął serię, która będzie opisywać zmagania z tworzeniem aplikacji do przechwytywania powiadomień z portalu dobreprogramy.pl w Windows 10 (+Mobile). Przyszedł zatem czas na coś konkretnego. Dziś przedstawię analizę, w jaki sposób na stronie zostało zrobione pobieranie powiadomień dla zalogowanego użytkownika.

Z jednej strony będzie to dobrym wstępem do kolejnych wpisów i podwaliny pod rozpoczęcie prac nad kodem, a z drugiej strony zapewne można będzie się czegoś ciekawego dowiedzieć o aplikacjach web :) (mam nadzieję :P )

Do dzieła! :)

Nie będzie tutaj żadnej magii. Poniżej analizujemy jedynie i obserwujemy, jak działa system powiadomień od strony przeglądarki. Bez ingerencji w kod portalu.

F12 - zaczynamy analizę!

Pracę rozpoczniemy standardowo, jak zawsze kiedy zabieramy się za bałagan po stronie frontendu, czyli od narzędzi deweloperskich w przeglądarce. Akurat z racji używania na co dzień Chroma, będzie to standardowe narzędzie dla programistów, dostępne zawsze pod klawiszem F12.

Gdzie na stronie są powiadomienia?

Na początku można wywnioskować, że powiadomienia są przesyłane jedynie na początku, przy ładowaniu strony. Zalogowany użytkownik dostaje wygenerowaną stronę, a w niej zawarty już kod HTML, który reprezentuje jego Centrum akcji.

Na szczęście tak nie jest, dzięki czemu zostaliśmy uchronieni przed parsowaniem kodu HTML za pomocą zewnętrznych bibliotek (takich jak np. HtmlAgilityPack).

Otóż, niedawno, całkiem przypadkiem, odkryłem że powiadomienia z portalu są dynamicznie pobierane. Zobaczymy to po przejściu na zakładkę Network, w narzędziach deweloperskich w Chrome.

W celu łatwiejszego odnalezienia szukanego serwisu, przefiltrujmy wyniki klikając na opcję XHR. Pozwoli to nam na wydzielenie jedynie wysyłanych zapytań na serwer.

Po chwili zobaczymy, że co ok. 12 sekund wysyłany jest request.

Strona wysyła zapytania na serwer pod adres (śmiało klikajcie!):

http://www.dobreprogramy.pl/Providers/NotifyHelper.ashx?ping=ping&_=znacznik_czasu

Gdzie znacznik czasu jest inkrementowaną datą wejścia na stronę w postaci milisekund. Możemy łatwo to sprawdzić wpisując w konsoli JS:

> new Date(1457379954093) < Mon Mar 07 2016 20:45:54 GMT+0100 (Środkowoeuropejski czas stand.)

Mamy zatem już nasze źródło danych. Zobaczmy zatem co jest w środku.

Zaglądamy do środka - lista powiadomień

Jeśli klikniemy w otwartej zakładce w narzędziu dev. na link, otrzymamy podgląd z otrzymanej wiadomości. Teraz po kliknięciu na zakładkę Preview ujrzymy sformatowany podgląd odpowiedzi z serwera. Eureka! :P

Okazuje się, że co 12 sekund otrzymujemy JSONa z listą aktualnych powiadomień! Możecie sami sprawdzić swoje dane klikając nawet na powyższy link, poprzedniego akapitu.

Otrzymane dane przechowywane są w liście current, gdzie każdy element jest powiadomieniem.

Każdy z elementów posiada Id, a także link z grafiką (pole Avatar), dodatkowy tekst (CustomText), datę (Data), status (Status), adres URL (TargetUrl), tytuł (Title), typ powiadomienia (Type) i osobę odpowiedzialną za aktywację powiadomienia (UserName).

Co ciekawe, klucz w postaci: NUMER1:NUMER1 określa kolejno ID wpisu na blogu/aktualności/linku do programu, zaś drugi numer to ID powiadomienia. Przyda się nam to za chwilę.

Zaglądamy do środka - akcje na liście

Zapewne zauważyliście, że można również oznaczać powiadomienia jako przeczytane i je usuwać:

Szybki podgląd w Networku wskazuje na to, że obie operacje są również wysyłane do tego samego serwisu (a dokładniej Handlera) NotifyHelper:

Wówczas wysyłamy jedynie dodatkowy komunikat, to czy chcemy usunąć powiadomienie (deleteNotify), czy tylko oznaczyć jako przeczytane (markAsRead). Okazuje się zatem, że oprócz pobierania powiadomień, będziemy mogli je prosto usuwać i dezaktywować!

Koniec?

Ufff. Dziś całkiem sporo udało się odsłonić z tego, jak działają powiadomienia na portalu, poprzez prostą analizę requestów w przeglądarce. Czy to zatem już koniec?

O nie :) To dopiero początek przygody :) Zostaje nam jeszcze jedno, chyba najważniejsze zagadnienie: skąd serwis wie, kto wysyła powiadomienia? Oczywiście wszystko znajduje się w przeglądarce użytkownika. Największym problemem będzie zatem dowiedzenie się co to jest i jak to wyłuskać, aby móc wysyłać i odbierać powiadomienia już nie z okna przeglądarki, ale z poziomu naszego własnego kodu. Te zagadnienie będę jednak starał się opisywać w kolejnych wpisach.

Zatem, do zobaczenia! :)

 

windows programowanie urządzenia mobilne

Komentarze

0 nowych
tylko_prawda   10 #1 09.03.2016 18:07

Jeżeli coś z tego będzie (aplikacja albo coś), to może przetestuję :P

arlid   14 #2 09.03.2016 19:14

Dobry wpis :) Taki trochę "hakerski". idę czytać kolejny!

Shaki81 MODERATOR BLOGA  37 #3 09.03.2016 19:47

Spokojnie z tym rozgryzaniem bo nam jeszcze portal zhakujesz:)

mordzio   14 #4 09.03.2016 19:48

Zostaw DP w spokoju, znając Twoje szczęście jeszcze coś popsujesz! ;p

AlbatrosZippa   10 #5 09.03.2016 19:52

Odblokuj wszystkim Bolda - oczywiście żartuje
A tak brakuje mi "Kasuj komentarze", bo mam w niektórych spam w opór

ziupo   6 #6 09.03.2016 20:17

A wystarczyło zapytać Redakcję ;)

SebaZ   15 #7 09.03.2016 20:47

@ziupo: nawet jakby zapytał to i tak musiałby wgryźć się w dane i kod, żeby móc je zinterpretować :P

wojtekadams   18 #8 09.03.2016 20:53

@djfoxer ty to się nudzisz w domu, prawda?

djfoxer   17 #9 09.03.2016 22:48

@tylko_prawda: Zapraszam :)


@arlid: Ten jeszcze nie jest "tak ciekawy", poczekaj na kolejny ;)

djfoxer   17 #10 09.03.2016 22:54

@Shaki81: @Lisek na to nie pozwoli ;)

@mordzio: Nawet jakbym chciał nic bym tu nie zepsuł, mimo nawet usilnych starań ;)

@AlbatrosZippa: Niektórzy blogerzy dostali przycisk "USUŃ" obok każdego komentarza pod ich wpisami na blogu. Jeśli go nie widzisz, napisz do Redakcji :)

@ziupo: Nie byłoby takiej zabawy, gdyby wszystko było podane na tacy ;) Poza tym nie ma ani dok., ani API, więc kolejne kroki, do zalogowania i zarządzania powiadomieniami z kodu, będą bardzo bardzo ciekawe :)

djfoxer   17 #11 09.03.2016 22:56

@SebaZ: No i gdzie tu przyjemność z własnego eksplorowania kodu :)

@wojtekadams: Nie, ale mam z tego mega dużą przyjemność i przy okazji czegoś można się nauczyć (np. apki uniwersalne) :D

AlbatrosZippa   10 #12 09.03.2016 23:04

@djfoxer: Będę musiał się tym zająć

tylko_prawda   10 #13 10.03.2016 06:15

@djfoxer: #9 Jak będzie za darmo dla Win7 albo Linuxa to mogę sprawdzić czy u mnie działa. Zgłaszam się na ochotnika, jeśli będzie za darmo mogę zostać beta- (albo stable-) testerem :-)
EDIT: A nie, ma być tylko na W10... a tam, ściągnę se wersję próbną na Virtualboxa!

Autor edytował komentarz.
paneres   3 #14 10.03.2016 08:49

Bardzo ciekawy wpis, może kogoś zainteresuje do głębszej nauki kodu ;)
A co do aplikacji to fajna sprawa, szkoda tylko że Windows a nie w formie dodatku do przeglądarki.

djfoxer   17 #15 10.03.2016 09:06

@tylko_prawda: Dzięki :)
@paneres: Dobry pomysł :) Jeśli zatnę się gdzieś na robieniu wersji apki uniwersalnej,. to w ramach oderwania mogę zrobić wtyczkę na Chrome :)

WODZU   16 #16 10.03.2016 13:10

Moje zdjęcie zostało wykorzystane w zamieszczonych tu zrzutach ekranowych bez mojej zgody, spotkamy się w sądzie ;P
A tak serio, to przypomniał mi się pewien człowiek, który straszył tu wszystkich sądem :D

Autor edytował komentarz.
Lisek REDAKCJA  12 #17 10.03.2016 20:09

@djfoxer - z wielkim zainteresowaniem czytam o Twoich zmaganiach :)
Pomyślałem sobie, że nie będę Ci podpowiadał, jestem naprawdę zaciekawiony postępami w rozgryzaniu jak to wszystko działa. Nie mniej jednak jak przeczytam, że zmierzasz w ślepą uliczkę, dam znać. Powodzenia :)

Pablo_Wawa   9 #18 10.03.2016 20:14

@djfoxer: Ładnie opisałeś tę ciekawą technikę wyłuskiwania przydatnych nam danych z serwisów internetowych. Miałeś szczęście, że w tym przypadku interesujące Cię dane były podane "na tacy" (jako JSON) - choć jeśli autor "źródłowej" aplikacji specjalnie tego nie utrudni (zaciemni), to jest to i tak zazwyczaj proste (nawet z kodu HTML - i nie potrzeba do tego zaraz go całego parsować - wystarczy używać wyrażeń regularnych).

W 2011 roku napisałem (głównie na swoje potrzeby) aplikację w JavaScripcie, pobierającą wszystkie wiadomości z mojego konta na portalu Nasza Klasa - raz żeby mieć ich kopię lokalnie na komputerze (na wypadek zniknięcia serwisu lub mojej rezygnacji z ich usług), dwa żeby mieć wygodniejsze narzędzie do przeglądania tych wiadomości, wyszukiwania w nich potrzebnych informacji oraz by móc wysyłać wiadomości do wielu osób naraz (interfejs tego portalu był mocno prymitywny i nie tego oferował). Mój interfejs przyglądania poczty wzorowałem na Outlook Expressie (co można zobaczyć na tym zdjęciu: http://i.imgur.com/UdUicxd.jpg).

Kilka lat temu, będąc "zmuszonym" do raportowana swojej pracy na HelpDesku w programie Mantis Bug Tracker (http://enterpriseblog.net/a/review-of-mantis-a-free-and-popular-web-based-bug-tr.../), który w sumie głównie służył tylko do robienia dla Zarządu zestawień czasu pracy i ilości zgłoszeń, jakie były obsługiwane przez HelpDesku z podziałem na poszczególne osoby, napisałem aplikację (w JavaScripcie), którą nazwałem przewrotnie "Mantis killer", służącą do automatycznego tworzenia losowych (ale sensownych) raportów w tym systemie (ustalałem głównie liczbę zgłoszeń do wygenerowania i rodzaje zgłoszeń). Opis tego projektu jest na stronie http://programistrz.pl/projekty/mantis/, jest tam też dostępny do pobrania/obejrzenia filmik z działania w praktyce tego programu. Wspominam o nim dlatego, że dane o konfiguracji Mantisa pobierałem "w locie" parsując kod HTML konkretnych stron www tej aplikacji i wyłuskując potrzebne mi informacje, które następnie były wyświetlane w moim panelu i używane przy generowanie losowych zgłoszeń.

Aktualnie zaś piszę aplikację do kontroli materiałów eksploatacyjnych (głównie tonerów) w kserach w firmie gdzie pracuję (i wczesnego ostrzegania o konieczności ich wymiany/zamówienia) - tutaj potrzebne dane (m.in. o poziomie tonerów) odczytuję poprzez wyłuskanie ich z odpowiedniej strony internetowej panelu zarządzania takim kserem (oczywiście jest logowanie - czyli trzeba odczytać zawartość cookies, panel sporo korzysta z JavaScriptu - więc jest to spore utrudnienie). Trzeba było przeprowadzić podobną analizę przesyłanych i odbieranych z ksera danych, jaką zrobił i opisał tutaj djfoxer. Wyłuskane dane zapisuję do bazy danych, potem analizuję i szacuję na bieżąco, kiedy mniej więcej skończy się dany toner w konkretnym kserze, co umożliwi zrobienie zestawienia na podstawie którego zamawiam potrzebne tonery (stronę napisanego przeze mnie panelu do zarządzania kserami z przykładowym wykazem drukarek można zobaczyć na tym zdjęciu: http://i.imgur.com/IZAMs82.jpg).

PS. czemu przy Twoich wypowiedziach mam "treść komentarza została ukryta"? Wiem jak to odkryć, ale czemu tak na "starcie" się zrobiło? Poza tym, jak chcię odkryć na stałe Twoje komentarze, to mam "Wystąpił błąd, uniemożliwiający stałe odkrycie komentarzy użytkownika".

Frankfurterium   9 #19 10.03.2016 20:25

@Pablo_Wawa: "nawet z kodu HTML - i nie potrzeba do tego zaraz go całego parsować - wystarczy używać wyrażeń regularnych"

Pierwsza odpowiedź, zwłąszcza druga część:
https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-s...

Pablo_Wawa   9 #20 10.03.2016 20:34

@Frankfurterium: chyba się nie zrozumieliśmy - dla mnie, żeby wyłuskać ze strony HTML kilka wartości (przykładowo poziom tonerów w kserze) wystarczy zastosować wyrażenie regularne, nie widzę najmniejszego powodu używać "kobyły", tj. parsera HTML/XML do przetworzenia pliku tekstowego HTML, żeby potem móc wyszukać w drzewie DOM kilka wartości - dla mnie jest to przerost formy nad treścią.

Autor edytował komentarz.
  #21 10.03.2016 21:30

@djfoxer Takie małe "ale" - system powiadomień rozróżnia czy karta jest widoczna, czy nie także nie karty działające w tle nie wysyłają tak często zapytań do serwera.

Swoją drogą jest mi miło, ale i głupio, że ktoś grzebie w jednym z moich ulubionych komponentów DP, jakie przyszło mi stworzyć :) Z drugiej strony właśnie parę rzeczy w tym mechanizmie bym zmienił (swoją drogą doceniam, że wychwyciłeś zabawę z identyfikatorami! ;))

Autor edytował komentarz.
djfoxer   17 #22 11.03.2016 00:21

@Lisek: Ciesze się, dzięki :) Analizowanie jak co działa daje sporo frajdy:) Ostatnio z logowaniem trochę miałem przygód bo nie zauważyłem, że macie dwa sposoby na logowanie do portalu :) Mam nadzieję, że to co wyjdzie finalnie będzie ciekawym projektem i przydatną apką :)

@WODZU Zostałeś gwiazdą ;)

djfoxer   17 #23 11.03.2016 00:33

@Pablo_Wawa: O proszę. Aż zajrzałem na Twoją stronę i zauważyłem, że pierwszy projekt zrobiłeś już w 1991 (System zarządzania pracą Hotelu Gołębiewski w Mikołajkach (DOS)). W 1991 roku, to ja jeszcze do szkoły nie chodziłem :) Bardzo ciekawe projekty. Zabezpieczenie gry na Atari i nawet w AMOSie programowałeś :) No no, jako fan retro będę musiał szerzej przyjrzeć się tym projektom :)

Co do wyłuskiwania danych z kodu. Tutaj jest spore pole do popisu :) W wielu przypadkach można uzyskać całkiem ciekawe dane i porobić coś na co backend nie jest przygotowany :)

Co do komentarzy to widocznie, gdzieś kiedyś musiałeś niechcący kliknąć na
przycisk "ukryj". Aczkolwiek błąd nie powinien wyskakiwać. Napisz na BugTrackerze o tym: http://www.dobreprogramy.pl/BugTracker.html
Pozdrawiam :)

djfoxer   17 #24 11.03.2016 00:38

@tomick: Można to potraktować jako rodzaj code review ;) :P A z widocznością kart nie sprawdzałem jak to działa, ok :)

djfoxer   17 #25 11.03.2016 00:40

@Lisek: Mam nadzieję, że w trakcie moich "prac" nie będziecie niczego zmieniali po stronie backendu w powiadomieniach i logowaniu, aby mi trochę "urozmaicić" robotę :P :D

Lisek REDAKCJA  12 #26 11.03.2016 07:52

@djfoxer: jak będzie potrzeba zmian, poinformuję Cię o tym fakcie.

Autor edytował komentarz.
Wokuo   7 #27 12.03.2016 00:57

@djfoxer: W sprawie logowania polecam zajrzeć do ciasteczek.

@Lisek: DP stoi na ASP.Net WebForms czy MVC (jeżeli tak, to która wersja)?

Autor edytował komentarz.
Pablo_Wawa   9 #28 15.03.2016 20:13

@djfoxer: dzięki. Gwoli ścisłości, to ja w AMOSie nigdy nie programowałem (to taki AMIGA BASIC), tylko kolega ze studiów, mający właśnie Amigę (i te "wojny ideologiczne" - co jest lepsze - PeCet czy Amiga). A ja dla niego pisałem funkcje związane z grafiką do jego gry - w Pascalu pod DOS (ale większość kodu była i tak w asemblerze), bazujące na takim działaniu jakie było właśnie w AMOSie na Amidze.
Z dużego projektu dotyczącego wyłuskiwania danych ze stron internetowych, to zapomniałem wspomnieć o "Wikipedii offline lokalnie na komputerze" (http://programistrz.pl/projekty/wikipedia/) - z tym, że tam pobieram i obrabiam kod HTML w PHP (a nie JavaScripcie), bo potem zapisuję go lokalnie na dysku.

A co do komentarzy, to nic nie robiłem w ustawieniach profilu od dawna, więc się nieco zdziwiłem - pomyślałem, że może Ty mnie nie lubisz (he he), czy to blokujesz dla osób spoza grona znajomych? Dziś mi się Twoje komentarze już nie ukrywają, jak to było wcześniej. Cuda, Panie, cuda! :)