dareks_

  • Dokumenty2 821
  • Odsłony753 730
  • Obserwuję431
  • Rozmiar dokumentów32.8 GB
  • Ilość pobrań361 988

Programista 2013 10

Dodano: 6 lata temu

Informacje o dokumencie

Dodano: 6 lata temu
Rozmiar :5.2 MB
Rozszerzenie:pdf

Programista 2013 10.pdf

dareks_ CZASOPISMA
Użytkownik dareks_ wgrał ten materiał 6 lata temu.

Komentarze i opinie (0)

Transkrypt ( 25 z dostępnych 76 stron)

10/2013 (17) www•programistamag•pl Cena 9.90 zł (w tym VAT 23%) Index: 285358 Certfikaty SSLThere is no app Arduino a sprawa wyświetlaczy • ASP.NET SignalR • Budowanie wiedzy w zespole. Główne błędy i strategie OpenGL 2D Jak one działają i jak to za- implementować w Javie Koncepty stojące za filo- zofią platformy Android Programowanie grafiki: o shaderach i teksturach Twitter Bootstrap Co nowego w wersji 3

4 / 10 . 2013 . (17)  / REDAKCJA/EDYTORIAL Nowe wydanie Programisty po raz siedemnasty gości już na Waszych półkach i czytnikach e-booków i ciągle nie brakuje w naszym miesięczni- ku ambitnych tematów. Lekturę numeru proponujemy zacząć od artykułu Łukasza Mazura nt. szybkiego i efektywnego tworzenia frontendów z użyciem frameworka Twitter Bootstrap. Artykuł ten stanowi kontynuację artykułu z poprzed- niego numeru Programisty. W tej części autor opisuje m.in. zmiany, któ- re pojawiły się w wersji 3.0, oraz wybrane komponenty, jakie możemy wykorzystać podczas tworzenia witryn. Następnie zachęcamy do łatwego do „przełknięcia” artykułu z zakresu tematyk miękkich. Michał Bartyzel i Mariusz Sieraczkiewicz opowiadają krótko o najczęstszych błędach podczas budowania wiedzy w zespole projektowym. Z kolei Sławomir Andrzejewski, codziennie pracujący nad zapewnieniem niezawodności sieci komórkowych, omawia dobre prak- tyki dotyczące przeprowadzania automatycznych testów akceptacyjnych. Ponadto polecamy artykuły naszych dwóch nowych autorów: teksty Mi- chała Charmasa będą traktować o zaawansowanych aspektach platfor- my Android, natomiast Rafał Jamróz krok po kroku podpowie, jak radzić sobie z utrzymaniem testów automatycznych. Na koniec kilka słów o następnym numerze Programisty. Wielkimi kroka- mi zbliża się rozszerzone wydanie grudniowe, a w nim znajdziecie szereg ciekawych, mamy nadzieję, tematów, na czele z „Bliżej Silikonu #2 – O analizie BIOS API, procesie ładowania jądra Windows, a także tworze- niu boot loadera dla własnego systemu”. Będzie to druga (i nie ostatnia) część cyklu autorstwa Gynvaela Coldwinda i Mateusza Jurczyka. Powiększone wydanie to również debiuty nowych autorów – Bartek Kuczyński zaproponuje temat „Vaadin 7 – naprawdę szybkie tworzenie aplikacji web w Javie”, a wszystkich amatorów elektroniki na pewno zain- teresuje artykuł Marka Klimowicza o robocie DIY reagującym na światło. Wkrótce w newsletterach, na WWW i Facebooku będziemy ujawniać więcej szczegółów na temat kolejnego wydania naszego magazynu. Tymczasem życzymy przyjemnej i owocnej lektury z poważaniem, Redakcja Wydawca: Anna Adamczyk annaadamczyk@programistamag.pl Redaktor naczelny: Łukasz Łopuszański lukaszlopuszanski@programistamag.pl Korekta: Tomasz Łopuszański Kierownik produkcji: Krzysztof Kopciowski bok@keylight.com.pl DTP: Krzysztof Kopciowski Dział reklamy: reklama@programistamag.pl tel. +48 663 220 102 tel. +48 604 312 716 Prenumerata: prenumerata@programistamag.pl Współpraca: Michał Bartyzel Mariusz Sieraczkiewicz Artur Machura Marek Sawerwain Łukasz Mazur Rafał Kułaga Sławomir Sobótka Michał Mac Gynvael Coldwind Bartosz Chrabski Michał Leszczyński Adres wydawcy: Dereniowa 4/47 02-776 Warszawa Druk: ArtDruk – www.artdruk.com ul. Napoleona 4 05-230 – Kobyłka Nakład: 4500 egz. * Redakcja zastrzega sobie prawo do skrótów i opracowań tekstów oraz do zmiany planów wydawniczych tj. zmiany w zapowiadanych tematach artykułów i terminach publikacji, a także nakładzie i objętości czasopisma. O ile nie zaznaczono inaczej, wszelkie prawa do wszystkich materiałów zamieszczanych na łamach magazynu Programista są zastrzeżone. Kopiowanie i rozpowszechnianie ich bez zezwolenia jest wzbronione. Naruszenie praw autorskich może skutkować odpowiedzialnością prawną, określoną w szczególności w przepisach ustawy o prawie autorskim i prawach pokrewnych, ustawy o zwalczaniu nieuczciwej konkurencji i przepisach kodeksu cywilnego oraz przepisach prawa prasowego. Redakcja magazynu Programista nie ponosi odpowiedzialności za szkody bezpośrednie i pośrednie, jak również za inne straty i wydatki poniesione w związku z wykorzystaniem informacji prezentowanych na łamach magazy­nu Programista. Wszelkie nazwy i znaki towarowe lub firmowe występujące na łamach magazynu są zastrzeżone przez odpowiednie firmy. Magazyn Programista wydawany jest przez Dom Wydawniczy Anna Adamczyk

SPIS TREŚCI BIBLIOTEKI I NARZĘDZIA Twitter Bootstrap – szybkie tworzenie witryn HTML. Co nowego w wersji 3..... Łukasz Mazur 6 ASP.NET SignalR – czyli aplikacje czasu bardzo rzeczywistego............................... Karol Rogowski 18 PROGRAMOWANIE APLIKACJI WEBOWYCH Certyfikaty użytkownika SSL – jak to ugryźć?.............................................................. Michał Leszczyński 28 PROGRAMOWANIE GRAFIKI Szybka grafika 2D: Shadery i tekstury........................................................................... BartoszTaudul 32 PROGRAMOWANIE SYSTEMÓW OSADZONYCH Arduino a sprawa wyświetlaczy......................................................................................... Marek Sawerwain 42 TESTOWANIE I ZARZĄDZANIE JAKOŚCIĄ Automatyczne testy akceptacyjne w procesie Continuous Delivery.......................... Sławomir Andrzejewski 52 LABORATORIUM BOTTEGA Zaawansowane programowanie na platformie Android. Część I: There is no app – kluczowe koncepty stojące za filozofią platformy Android... Michał Charmas 56 Refaktoryzacja testów legacy w kierunku wykonywalnych specyfikacji. Część I: Podstawowy refaktoring testów......................................................................... Rafał Jamróz 60 PLANETA IT Java nad Wisłą..................................................................................................................... Łukasz Sobótka 68 KLUB LIDERA IT Budowanie wiedzy w zespole. Główne błędy i strategie............................................... Michał Bartyzel, Mariusz Sieraczkiewicz 70 KLUB DOBREJ KSIĄŻKI Programowanie. Teoria i praktyka z wykorzystaniem C++...................................... Rafał Kocisz 72 Domain-Driven Design: Tackling Complexity in the Heart of Software................ Sławomir Sobótka 74 Zamów prenumeratę magazynu Programista bezpośrednio u nas przez formularz na stronie http://programistamag.pl/typy-prenumeraty/ lub zrealizuj ją na podstawie faktury Pro-forma. W spawie faktur Pro-Forma prosimy kontktować się z nami przez e-mail redakcja@programistamag.pl. Prenumerata realizowana jest też przez RUCH S.A: Zamówienia na prenumeratę w wersji papierowej i na e-wydania można składać bezpośrednio na stronie www.prenumerata.ruch.com.pl Ewentualne pytania prosimy kierować na adres e-mail: prenumerata@ruch.com.pl lub kontaktując się z Telefonicznym Biurem Obsługi Klienta pod numerem: 801 800 803 lub 22 717 59 59 – czynne w godzinach 7:00 – 18:00 (koszt połączenia wg taryfy operatora).

6 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA Łukasz Mazur SŁOWEM WSTĘPU ... Dzisiaj Internet jest bardzo ważnym medium, w którym można znaleźć większość potrzebnych nam informacji. Podstawowym składnikiem Interne- tu są strony i witryny www. Są one wizytówkami firm, blogów, poradników czy różnych portali. Ważne jest, aby były one estetyczne i intuicyjne dla użyt- kownika. Do ich budowy w większości używamy języka HTML w połączeniu z arkuszem stylów CSS, które są interpretowane przez przeglądarkę i wyświe- tlane na ekranie urządzenia (już nie tylko komputerów). Responsywne strony Obecnie wiele osób korzysta z urządzeń przenośnych takich jak: smartfony, tablety czy ultrabooki, gdzie wielkość ekranu jest inna niż na komputerze typu desktop (czy na laptopach). Aby strona wyświetlała się na tego typu urządzeniach prawidłowo,możnaużyćdobudowywitrynyframeworkaTwitterBootstrap.Możli- wośćtworzeniaresponsywnychstroninternetowychorazdodatkowewsparciedla wielu gotowych rozwiązań czyni ten framework niezwykle przydatnym. O Bootstrapie ... Kilka słów przypomnienia o frameworku Twitter Bootstrap. Jest to narzędzie mające ułatwić pracę developerom aplikacji webowych. Pozwala ono na łatwe i szybkie tworzenie aplikacji w oparciu o standardy CSS i JavaScript. Powstał z po- trzeby eliminacji problemów związanych z interfejsem graficznym tworzonych aplikacji w firmie Twitter. Początkowo próbując rozwiązać te problemy, develo- perzy korzystali z wielu wzajemnie niekompatybilnych bibliotek. Aby temu za- pobiec, inżynierowie współpracujący z serwisemTwitter zdecydowali się opraco- wać jeden, kompleksowy i w pełni spójny zestaw narzędzi developerskich. W gruncie rzeczy Twitter Bootstrap to zestaw bibliotek CSS. Tym, co wy- różnia go od podobnych rozwiązań, jest jego architektura. Framework oparty został o elastyczny preprocesor LESS. Uzyskamy dzięki temu szereg przydat- nych funkcji, m.in: • możliwość zagnieżdżania deklaracji, • operacje oraz funkcje koloru itp. PonadtoTwitter Bootstrap jest bardzo łatwy do wdrożenia, a kompilacji LESS można dokonać, używając np. JavaScript. Po kompilacji pakietów, Twitter Boot- strap zawiera jedynie czysty CSS bez zbędnych dodatków, takich jak obrazy czy kod JavaScript. Gwarantuje to szybkość działania oraz wysoki komfort użycia. W poprzedniej części omówiono pobieranie, instalacje oraz uruchomie- nie podstawowej strony wykonanej przy użyciu Twitter Bootstrap. W tej czę- ści postaramy się przedstawić kilka wybranych komponentów (w tym opisać bardziej szczegółowo tworzenie tabel oraz wykorzystanie karuzeli), które z Twitter Bootstrap – szybkie tworzenie witryn HTML. Co nowego w wersji 3 OmówieniewybranychelementówwTwitterBootstrap W pierwszej części artykułu wyjaśniliśmy, jak zacząć przygodę z Twitter Bootstrap. Nato- miast w tej części postaramy się przybliżyć ciekawsze jego elementy. Zaprezentowane zostaną takie składniki jak wybrane komponenty, elementy JavaScript'u, w tym ich za- stosowanie oraz finalnie responsive design. Dodatkowo opiszemy, co nowego pojawiło się w wersji v3.0.0, czyli jakich zmian można się spodziewać w najnowszej odsłonie. pewnością wzbogaca naszą witrynę, oraz dodatkowo zestawione będą waż- niejsze zmiany, które wystąpiły w wersji v3.0.0. TWITTER BOOTSTRAP V3.0.0 – ZMIANY W drugą rocznicę releasu Twitter Bootstrap, dostarczono jego wersję v3.0.0. Dla autorów zapewne to była szalona, długa i mozolna praca, ale final- nie produkt jest już dostępny. Wszyscy, którzy wzięli udział w testowaniu wer- sji RC (beta) oraz zgłaszali błędy czy także ulepszali kod, otrzymali od autorów wielkie i szczere podziękowania. Bardzo ciężko było by opracować tego typu narzędzie bez wsparcia społeczności. Nowy Bootstrap Niestety, już na samym początku potrzeba powiedzieć, żeTwitter Bootstrap v3.0.0 może wprowadzić obecnych użytkowników w lekkie zakłopotanie, a szczególnie za sprawą re-designu. Po gruntownym przeglądnięciu wprowa- dzonych zmian można stwierdzić, że najświeższe wydanie może nie być naj- lepsze dla wszystkich. Kiedy tylko przyjrzymy się dokumentacji, bez problemu zauważymy, że wybrane aspekty kodu zostały sporo zmienione. W tym przy- padku raczej nie jest to najlepszym rozwiązaniem (generalnie w softwarze wy- chodzi to zazwyczaj na plus). Jednak teraz będziemy zmuszeni do pewnego ro- dzaju przebudowy naszych aplikacji (czy też stron www) w próbie ewentualnej migracji do nowej wersji. Główna, podstawowa struktura pozostała praktycznie bez zmian. Jedynym wyjątkiem jest opcjonalna możliwość dodania responsyw- nych elementów dla przeglądarki Internet Explorer 8 (Listing 1). Listing1.SzablonpodstawowejstrukturystronyzwykorzystaniemBootstrapBootstrap 101 Template

Hello, world!

7/ www.programistamag.pl / TWITTER BOOTSTRAP – SZYBKIE TWORZENIE WITRYN HTML Została sporo zmieniona praca grid systemu, o czym później. Również do- myślnie mamy włączony tryb responsive i nie ma już potrzeby, aby decydo- wać, czy dołączyć bootstrap-responsive.less, oczywiście jest także możliwość jego wyłączenia. Teraz można wybierać pomiędzy klasami, jak .col-sm dla małych gridów czy .col-lg dla dużych. Oznacza to, że można dokładniej precyzować, jak witryna będzie działać na smartfonach i tabletach, w przeci- wieństwie do komputerów stacjonarnych. Używając kodu: div.sidebar { make-column(3); } możemy utworzyć elementy zachowujące się jak kolumny, mimo że same nie mają znaczników elementu. Twitter Bootstrap nie wspiera już domyślnie starych przeglądarek. Jeżeli jednak koniecznie chcemy włączyć możliwie najstarszy tryb zgodności dla IE, powinniśmy w meta tagach witryny dodać następujący wpis:Nieco bliżej szczegółów Nadal są wykorzystywane ikony ze zbioru Glyphicons, które zostały od- świeżone i odrestaurowane. Można stwierdzić, że największym zmianom zo- stał poddany grid system Bootstrapa. W dokumentacji widnieją nowe nazwy klas CSS. Wprawiają one w lekkie zakłopotanie, jednak przy dłuższej pracy z nimi nabierają dosyć logicznego sensu. Nie zmienia to jednak faktu, że tego typu zmiany mogą wprowadzić niemało zamieszania i wymusić "przestawie- nie się" na nowe nazewnictwo. Na szczęście wszelkie widoczne poprawki typograficznych elementów nie zostały wprowadzone. Możemy cieszyć się tekstem (przynajmniej w skompilowanej wersji) rodem z Twitter Bootstrap 2.3.2. Formularze i buttony należą do grupy elementów, które zyskały nowy świeży wygląd, jednym się to spodoba, innym przeciwnie (flat design). Najświeższe trendy wyolbrzymiają większość elementów, jednak ogromne inputy tekstowe są mało poręczne. Drugą zmianą w designie jest usunięcie wypukłości z kolorowych buttonów. O ile te z poprzedniej wersji były całkiem ładne, to w tej chwili stały się trochę monotonne i jednokolorowe. JavaScrip- t'owe dodatki pozostały w większości bez zmian. Oczywiście poprawiono ich design, który jednym jak zwykle przypadnie do gustu, a innym już nie. Gene- ralnie należy zwrócić również uwagę na dwojakie spojrzenie przez autorów Twitter Bootstrap. Z jednej strony stawiają na minimalizm (płaskie buttony), a z drugiej wciąż pozostawiono cienie wielu elementów – można postawić tu małe pytanie: czy takie częściowo sprzeczne działania razem dobrze się komponują? Podsumowanie zmian Dla tych, którzy nie mieli okazji śledzić bieżących zmian, oto krótkie zesta- wienie tych ważniejszych, które wystąpiły w Bootstrap v3.0.0: • Nowy design oraz opcjonalne motywy: w wersji v3.0.0 postawiono na pła- ski flat design. Jak twierdzą autorzy, to nie jest tendencja – to wszystko po to, aby ulepszyć możliwości dostosowywania. Uproszczona została estetyka wyglądu, gdzie opcjonalny wybór tematu będzie z pewnością pomocny. • Mobilne urządzenia na plan pierwszy (zawsze responsywne): prawie wszystko zostało przeprojektowane i przebudowane, tak aby rozpocząć od urządzeń przenośnych i skalować projekt w górę. • Nowy Customizer: narzędzie zostało przeprojektowane, teraz elementy są zgromadzone w przeglądarce zamiast w bazie Heroku. Posiada lepszą obsługę zależności i dodatkowo ma wbudowaną obsługę błędów. Teraz wygodniej możemy zapisać preferencje jako anonimowy gest dla łatwego ponownego ich wykorzystania, udostępniania czy modyfikacji. • Lepszy domyślny box model: wszystko w Bootstrap przyjmuje teraz box-sizing: border-box, co dostarcza możliwości łatwiejszego dosto- sowania rozmiaru i lepszej manipulacji w rozbudowanym grid systemie. • Super-powered grid system: z czterema poziomami klas siatki, odpo- wiednio dla: telefonów, tabletów, komputerów stacjonarnych i dużych komputerów stacjonarnych. • Przepisane wtyczki JavaScript: wszystkie zdarzenia obecnie znajdują się w przestrzeni nazw, rzeczy no-conflict działają teraz o wiele lepiej i efektowniej. • Ikony Glyphicons: przywrócono Glyphicons do głównego repozytorium. W wersji 2.x występowały jako obrazki, teraz są one w formacie czcionki i obejmują 40 nowych glifów. • Zregenerowany pasek nawigacyjny: teraz jest on zawsze responsive i został wyposażony w kilka przydatnych komponentów. • Elementy modalne są bardziej elastyczne: przeprowadzono remont tej części kodu, aby elementy były bardziej responsywne na urządzeniach mobilnych. Teraz można przewijać obszar renderowania zamiast wcze- śniej ustawionego sztywno max-height. • Usunięto wybrane składniki: odrzucony został accordion (zastąpiono go składanymi panelami), submenu oraz wpisywanie znaków z wyprzedzeniem. • Bardziej spójne klasy: przyciski, tabele, formularze, alerty i inne zostały zaktualizowane, po to aby uzyskać bardziej spójne klasy dla łatwiejszego konfigurowania i rozszerzalności. • Dodano nową dokumentację: nie tylko dla komponentów, ale dotyczą- ce także wsparcia przez przeglądarki (w tym pułapek i różnych błędów), najczęściej zadawane pytania FAQ odnośnie licencji, wsparcia dla kompo- nentów third party oraz odnośnie dostępności. • Odrzucony support dla Internet Explorer 7 i Firefox 3.6: dla Internet Explorer 8 potrzeba dołączyć Respond.js dla wszystkich Media Queries w celu pracy w pełnym zakresie. Dla osób testujących prerelease i innych, które posiadają jeszcze wersję RC, poniżej zestawiona została lista niektórych z bardziej znaczących zmian wprowadzonych do RC: • Zostały naprawione błędy zgłoszone w wersji RC, • Odrestaurowano Glyphicons, • Komponenty NavBars teraz wymagają .navbar-default dla wersji standardowej, • Panele teraz wymagają .panel-default dla standardowej (szarej), • Alerty wymagają teraz klasę modyfikującą (np. .alert.alert-warning – dla domyślnego wcześniej żółtego alertu), • Wiele responsywnych narzędzi może być zastosowanych do tego samego elementu, • Przykłady są z powrotem w głównym repozytorium i zostały w pełni zaktualizowane, • Błędy kompilacji Customizera zostały naprawione, • Dodano opcjonalne motywy, • Jumbotrony są teraz wykonane w taki sposób, aby przedłużyć szerokość obszaru wewnątrz kontenera. Odwracając to, spowodujemy, iż jumbotron w kontenerze zostanie zaokrąglony i wcięty. Rysunek 1. PrzykładJumbotronu • Składniki NavBar zostały usprawnione z uwagi na obecność kontenerów i innych elementów. • Można zobaczyć kilka nowych modyfikacji w marginesach i wcięciach, ale zmiana znaczników nie powinna być do tego wymagana.

8 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA WYBRANE KOMPONENTY Kolejno zostanie zaprezentowanych kilka ważniejszych (ciekawszych) komponentów, wchodzących w skład frameworka. W sekcji Bootstrapa (Com- ponents) zgromadzono podstawowe style dla elementów interfejsu, takich jak karty z treścią, panele nawigacyjne, paski postępu, przyciski, okienka komunikatów (informacyjne, ostrzegawcze, błędów), nagłówki itp. Podczas budowy naszej strony jest niezmiernie przydatnym, iż mamy tyle rzeczy do wykorzystania niewielkim nakładem pracy – czy wręcz za darmo. Postaramy się krótko zaprezentować kilka wybranych komponentów (ze względu na dużą ich ilość nie sposób przedstawić wszystkich, więc w celu dokładnego przejrzenia zachęcam do odwiedzenia strony Bootstrapa). Komponenty zostały przedstawione na Rysunkach od 2 do 8. Kod użyty do ich wyświetlenia zamieszczono na Listingach od 2 do 8. Rysunek 2. Przykład dostępnych różnych typów alertów Listing 2. Definiowanie alertów

...
...
...
...
Rysunek 3. Przykład dostępnych typów alertów z odnośnikami Listing 3. Definiowanie alertów z odnośnikamiRysunek 4. Przykład grupowania inputów Listing 4. Definiowanie grupowania inputówRysunek 5. Przykładowy pasek nawigacji Listing 5. Definiowanie paska nawigacji
Grupowanie przycisków Przyciski nie muszą być pojedyncze, możemy tworzyć z nich grupy, grupy grup, ustawiać je w pionie i zmieniać ich rozmiary. Grupę przycisków tworzymy poprzez zamknięcie ich w div z klasą .btn-group. Bootstrap zadba, by pierwszy i ostatni z nich miały zaokrąglone rogi, a środkowe były prostokątami (Rysunek 6). Rysunek 6. Pojedyne przyciski i ich grupowanie w różnych konfiguracjach Listing 6. Definiowanie grupy przycisków
...
...
...
...
Rysunek 7. Różne warianty przycisków typu dropdown Listing 7. Definiowanie przycisków typu dropdownRysunek 8. Komponenty stronicowania (różne rozmiary) Listing 8. Definiowanie komponentów stronicowania
    ...
    ...
    ...
TABELE Przejdźmy teraz do opisu tabel. Jak wiemy, tabele bardzo często znajdują swoje zastosowanie w wielu biznesowych rozwiązaniach. Twitter Bootstrap posiada kilka klas, które umożliwiają ich dostosowywanie, a także zapewniają estetyczny wygląd. Podstawowa tabela Tabele tworzymy poprzez HTMLowy znacznik ...
, gdzie wystarczy dodać do niego klasę .table, by uzyskać w niej dopełnienie, czy poziome linie oddzielające poszczególne wiersze (Listing 9). Listing 9. Definiowanie prostej tabeli...
#NameSurname
1JohnDoe
2JamesSmith
Dodatkowe klasy tabeli Do klasy .table możemy dołączyć kilka opcjonalnych klas zmieniają- cych sposób jej wyświetlania. Klasa .table-striped powoduje dodanie ciemniejszego tła do co drugiego wiersza tabeli (Listing 10). Listing 10. Ciemniejsze tło dla co drugiego wiersza w tabeli...
Klasa .table-bordered automatycznie dodaje obramowanie do tabeli (Listing 11). Listing 11. Obramowanie tabeli...
Klasa .table-hover powoduje podświetlenie wiersza, nad którym ak- tualnie znajduje się kursor myszy (Listing 12). Listing 12. Podświetlenie wiersza w tabeli...
Klasa .table-condensed zmniejsza dopełnienie wewnątrz tabeli (Li- sting 13).

10 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA Listing 13. Zmniejszenie dopełnienia wewnątrz tabeli

...
Dodatkowe klasy wierszy Dzięki zastosowaniu klas .success, .error, .warning oraz .infomożli- we jest nadawanie kolorów poszczególnym wierszom w tabeli (Listing 14). Listing 14. Nadawanie kolorów poszczególnym wierszom w tabeli...
#NameSurname
1JohnDoe
2JamesSmith
2PaschalMoris
Oczywiście możliwe jest stosowanie wielu klas dla tabeli, tak aby dostoso- wać jej wygląd do naszych wymagań (Listing 15). Listing 15. Wykorzystanie wielu klas w tabeli...
#NameSurname
1JohnDoe
2JamesSmith
2PaschalMoris
Bardzo zachęcam do eksperymentowania, gdyż ten komponent posiada szerokie możliwości i będzie bardzo przydatny, wzbogacając wszelkiego ro- dzaju witryny wyświetlające wyniki analiz lub strony prezentujące grupowa- ne dane w zwięzłej formie tabelarycznej. KARUZELA Karuzela służy do tworzenia galerii obrazów, które przewijamy za pomocą elementów nawigacyjnych (strzałki) lub może odbywać się to automatycznie. Zwykle wykorzystywana jest ona w głównej części strony, gdy chcemy po- chwalić się swoim portfolio czy też przekazać ważne informacje o zawartości naszego serwisu (np. kilku produktach). Należy pamiętać, iż rzadko użytkow- nik będzie przewijał 50 czy więcej slajdów, więc lepiej zamieścić w niej rzeczy najważniejsze z naszego punktu widzenia. Rysunek 9. Komponent karuzela Od strony programistycznej, gdy nie zamkniemy karuzeli w kontenerze, będzie ona sięgała krawędzi okna przeglądarki, niezależnie od rozdzielczości. Wspomniany kontener doda jej marginesy po bokach, a umieszczenie jej w kolumnie pozwoli nam na ustalenie pożądanego rozmiaru. Występują dwa rodzaje karuzeli: z opisem oraz bez opisu. Różnicą w kodzie jest dodanie tylko jednego znacznika div (Listing 16). Listing 16. Zamknięcie komponentu karuzeli w znaczniku divgdzie id="carousel-example-generic" to dowolna nazwa kompo- nentu, którą będziemy później wykorzystywać. Odnośniki do slajdów Kolejnym etapem w tworzeniu karuzeli są kropki (indykatory), które po- zwalają przenieść się do konkretnego slajdu (Listing 17). Listing 17. Dodanie nawigacji do karuzeliZapis data-target="#carousel-example-generic" musi prowadzić do nazwy naszej karuzeli. A ilość wpisów w znaczniku
  • ...
  • musi być równa ilości slajdów. Klasa class="active" oznacza, który slajd ma być pierw- szy. Oczywiście tak jak cały kod, są one wewnątrz pierwszego znacznika div. Dołączenie slajdów Nasze obrazki, które chcemy dodać, zamykamy również w znaczniku div (Listing 18). Listing 18. Obrazki zamknięte w znaczniku divDodatkowo wewnątrz znacznika każdy obrazek musi znajdować się w ko- lejnym znaczniku div (Listing 19).

    1and1.pl NOWE DOMENY NOWE MOŻLIWOŚCI DOMENY | E-MAIL | STRONY WWW | HOSTING | SERWERY Teraz w ofercie 1&1 mamy już ponad 700 nowych domen najwyższego poziomu (nTLD). Stwórz chwytliwy adres, np. nowak.shop, serwis.auto lub winiarnia.online i używaj go jako głównej lub dodatkowej domeny dla Twojego serwisu. Będziesz jeszcze lepiej widoczny w Internecie! W 1&1 zarejestrowaliśmy już około 20 milionów domen, co czyni nas największym europejskim rejestratorem. Dzięki funkcji przekierowania, z łatwością połączysz zarejestrowaną u nas domenę ze swoją stroną internetową, nawet jeśli jest ona hostowana przez inną firmę. Więcej informacji na 1and1.pl TERAZ REZERWUJ ZA DARMO I BEZ ZOBOWIĄZAŃ!* *Wstępna rezerwacja nTLD jest bezpłatna i nie gwarantuje, że domena zostanie zarejestrowana. O przyznawaniu wstępnie zarezerwowanych nTLD decydują niezależne od 1&1 rejestry domen. Więcej informacji na 1and1.pl oraz w regulaminach rejestrów domen.

    12 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA Listing 19. Kolejny obrazek zamknięty w znaczniku div

    Podołączeniuopisówdoslajdównaszkodbędziesięprezentowałnastępująco: Listing 20. Dołączenie opisów do slajdów
    Klasa
    wskazuje nam na pierwszy slajd, który będzie wyświetlany. Przewijanie Tworzona karuzela powinna także posiadać po bokach strzałki do przewi- jania. Tworzymy je następująco (Listing 21): Listing 21. Utworzenie strzałek w celu nawigacjiJak możemy zauważyć podczas użycia znaczników zakotwiczania we- wnątrz odwołujemy się do nazwy naszej karuzeli, używając referencji href="#- carousel-example-generic". Odwołania te służą temu, by można zamieścić na stronie więcej niż jeden slider i sterować każdym z nich niezależnie. Na tym kończymy budowę naszej karuzeli. Po połączeniu opisanych ele- mentów można umieścić gotowy komponent na stronie i sprawdzić jego działanie. Po udanej integracji, oczywiście można dowolnie rozszerzyć/wzbo- gacić zaprezentowane rozwiązanie. MENU STRONY Podstawowa wersja menu Kolejno zostanie przedstawiony krótki opis jakże ważnej funkcjonalno- ści, czyli menu. Większość stron internetowych posiada menu, które w dużej większości jest umieszczone w górnym jej obszarze. Jest to pewien standard i użytkownicy są do tego przyzwyczajeni. Pokażemy więc, jak wykonać proste menu, dodatkowo wzbogacając je o rozwijaną listę. Podstawowe menu składa się z tytułu strony i linków do podstron oraz musi się znajdować w “kontenerze” (.container). Znaczniki div z klasami .navbar oraz .navbar-inner tworzą pasek menu. Tytuł strony wystarczy umieścić w kotwicy z klasą .brand. Kolejne linki muszą znajdować się na liście z klasą .nav. Pusty element listy z klasą .divider-verical oddziela kolejne elementy pionową kreską. Definicję przedstawiono na Listingu 22. Listing 22. Definiowanie podstawowego menuFormularz i wyszukiwanie w menu W pasku menu możemy także umieścić pole formularza lub wyszukiwa- nia. Wystarczy w środku menu utworzyć formularz z klasą .navbar-form lub .navbar-search i to wszystko. Przykład przedstawiono na Listingu 23. Listing 23. Definiowanie pola formularzaRozwijane menu Możemy również stworzyć listę, która rozwija się po kliknięciu na nią mysz- ką. Element menu, który ma być rozwijany, musi otrzymać klasę .dropdown, a następnie musimy wstawić następujący kod przedstawiony na Listingu 24. Listing 24. Definiowanie rozwijanego menu ...Element Name... Dzięki temu otrzymamy rozwijany element, gdzie użyty kod odpowiada za ikonkę-strzałkę skierowaną w dół. Element listy z klasą .divider wyświetla poziomą linię oddzielającą. Połączenie opisa- nych elementów przedstawiono na Listingu 25.

    13/ www.programistamag.pl / TWITTER BOOTSTRAP – SZYBKIE TWORZENIE WITRYN HTML Listing 25. Przykład rozwijanego menu

    ELEMENTY JAVA SCRIPT'U Dodatki JavaScript (JavaScript Plugins) są bardzo przydatne wszędzie tam, gdzie zachodzi potrzeba umieszczenia interaktywnych elementów do witry- ny takich jak: slidery, okienka akcji, tooltip'y, rozwijane menu itp. Właśnie ta- kiego rodzaju elementy również zostały zaimplementowane w Bootstrap'ie, po to, aby można łatwo z nich korzystać w projektach. Kolejno przedstawimy tylko kilka wybranych komponentów (ponieważ wszystkich jest dosyć sporo), aby pokazać, czego można się spodziewać (i próbować je wykorzystać) w tej kategorii Bootstrapa podczas budowania witryny. JavaScript alert Przedstawiającelementyskładowe,wartonawstępiepowiedziećoalertach posiadających możliwość oprogramowania zdarzeń dla funkcjonalności zamy- kania. Wywołanie metody: $().alert() uzupełnia wszystkie klasy .alert o funkcjonalność zamykania. Aby animować alert, podczas zamykania, upewnić się potrzeba, iż klasy .fadeoraz .in są aktualnie dołączone do zastosowanego znacznika. Wywołanie metody: $(".alert").alert('close') powoduje jawne zamknięcie alertu. Klasa Bootstrap .alert udostępnia nam kilka zda- rzeń dla połączania się z funkcjonalnością alertów, oto przykłady: • close.bs.alert – zdarzenie jest wyzwalane natychmiast po tym, gdy metoda bliskiej instancji jest wywołana. • closed.bs.alert – zdarzenie jest wyzwalane po tym, gdy alert został zamknięty. Rysunek 10. Przykład alertu Listing 26. Wywołanie alertu $(".alert").alert() Aby uzyskać automatycznie funkcjonalność zamykania naszego alertu, wystarczy po prostu dodać data-dismiss="alert" do kodu wybranego przycisku. Listing 27. Dodanie funkcji zamykania dla alertuModalne okna JavaScript Okna modalne są przejrzyste, proste, ale i elastyczne, tzw dialogowe prompty z minimalną (wymaganą) funkcjonalnością oraz posiadające inte- ligentne wartości domyślne. Aby renderowanie modalnego okna z nagłów- kiem mogło się odbyć, ciało oraz zestaw akcji powinien być umieszczony w stopce strony. Chcąc uruchomić okna poprzez tzw. atrybuty danych (czyli aktywacja okna bez użycia kodu JavaScript'u), potrzebujemy wykonać co następuje. A mianowicie, ustawiamy data-toggle="modal" na elemencie kontrolera (może nim być przykładowy przycisk), wraz z data-target="#- foo" lub href="#foo", odnosząc się do określonego okna modalnego w celu jego przełączenia. Użycie wewnątrz znacznika:Z drugiej strony chcąc uruchomić okno, wykorzystując kod JavaScrip, wywoła- nie takie (zakładając, iż id okna ma wartość myModal) prezentuje się następująco: $('#myModal').modal(options). Rysunek 11. Przykład wyświetlania modalnego okna Listing 28. Deklaracja w kodzie modalnego oknaJavaScript – popovery i tooltipy Popover w Bootstrap jest tworzony przy użyciu niestandardowej wtyczki jQuery. Może być używany do wyświetlania różnorakich informacji każdego elementu. Poniżej można będzie zobaczyć, jak używać od początku popover i tooltip, a także jak je dostosować za pomocą kilku dostępnych opcji.

    14 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA Musimy dołączyć jQuery, Twitter Bootstrap CSS i dwa pliki JavaScript – je- den dla komponentu tooltip Twitter Bootstrap i jeden dla popover Twitter Bootstrap. Plik JavaScriptu popover jest dostępny w folderze JS z pakietu Twitter Bootstrap jako bootstrap-popover.js oraz plik JavaScriptu dla tooltip jest dostępny w folderze JS jako bootstrap-tooltip.js. JQuery jest dostępny pod docs/assets/js jako jquery.js, lub może wskazywać na ten URL: http://code.jqu- ery.com/jquery-1.10.2.min.js. Popovery w grupach przycisków i grupach wejść wymagają specjalnych ustawień. Podczas korzystania z popoverów na elementach .btn-group lub .input-group, będziemy musieli określić opcję .container:'body', aby uniknąć niepożądanych efektów ubocznych (takich jak szersze elementy lub utrata zaokrąglonych rogów, gdy popover jest wyzwalany). Dostępne są cztery opcje umiejscowienia: top, right, bottom i wyrów- nanie do lewej left. Ze względu na aspekty wydajności, API dla tooltip'ów i popover'ów są typu option-in. Jeśli chcemy ich używać, potrzebujemy określić więc opcję selektora. Poniżej zostaną wymienione poszczególne opcje uruchamiające komponent. • $().popover(options). • $('#element').popover('show') – pokazuje popover dla elementu. • $('#element').popover('hide') – ukrywa popover dla elementu. • $('#element').popover('toggle') – przełącza popover dla elementu. • $('#element').popover('destroy') – usuwa popover dla elementu. Rysunek 12. Przykład popoverów Przykład: $('#myPopover').on('hidden.bs.popover', function () { // do something }) Rysunek 13. Przykład tooltipów Podobnie jak popovery – tooltipy w grupach przycisków i grupach wejść wymagają specjalnych ustawień. Podczas korzystania z tooltipów na ele- mentach .btn-group lub .input-group będziemy musieli określić opcje .container:'body'', aby uniknąć niepożądanych efektów ubocznych (ta- kich jak szersze elementy lub utrata zaokrąglonych rogów, gdy tooltip jest wyzwalany). Opcje dla poszczególnych tooltipów można alternatywnie okre- ślić z wykorzystaniem atrybutów danych, jak pokazano poniżej: Użycie wewnątrz znacznika:Hover over mePoszczególne opcje uruchamiające komponent: • $().tooltip(options). • $('#element').tooltip('show') – pokazuje tooltip dla elementu. • $('#element').tooltip('hide') – ukrywa tooltip dla elementu. • $('#element').tooltip('toggle') – przełącza tooltip dla elementu. • $('#element').tooltip('destroy') – usuwa tooltip dla elementu. Przykład: $('#myTooltip').on('hidden.bs.tooltip', function () { // do something }) RESPONSIVE WEB DESIGN Responsive Web Design jest funkcjonalnością zapewniającą użytkow- nikowi uzyskanie najlepszych odczuć (user experience) podczas przeglą- dania stron internetowych na różnych urządzeniach (posiadających różne rozmiary). Na przykład, w przypadku przeglądania strony internetowej na monito- rze komputera, a następnie wyświetlania jej na smartfonie (gdzie rozmiar jest mniejszy niż rozmiar monitora komputera), nie powinna występować większa różnica podczas pracy z UI. Inaczej mówiąc, powinniśmy mieć złudzenie, iż jesteśmy w tym samym serwisie (miejscu). Chcąc uzyskać tego typu wrażenia, potrzeba na takiej stronie uaktywnić elementy odpowiedzialne za mecha- nizm responsive design. Aby testować zachowanie strony, można zmieniać rozmiar przeglądarki za pomocą zmiany rozmiaru okien. Pomocnym będzie wtedy rozszerzenie Window Resizer dla przeglądarek Chrome czy Firefox. Jak działa responsive design? Do pracy z responsive design potrzeba stworzyć CSS, który zawiera style odpowiednie dla różnych urządzeń o róż- nych zakresach rozmiarów. Gdy strona ma się załadować na konkretnym urządzeniu, za pomocą różnych technik front-endu jak kwerendy mediów (Media Queries – które pozwalają dostosować styl do dokumentu oparty na środowisku, w którym dokument ten jest renderowany), wielkość obszaru wyświetlania musi zostać wykryta, po czym specyficzny styl dla urządzenia jest ładowany. Przejdźmy teraz nieco w głąb Responsive Design CSS początkowo opie- rając się na przykładzie wcześniejszej wersji Bootstrapa v2.3.2. Weźmy pod uwagę integrację 'bootstrap-responsive.css' z naszą stroną i postarajmy się zro- zumieć, w jaki sposób działanie tego mechanizmu zostało osiągnięte. Na wstępie musimy pamiętać, iż potrzeba dodać następujący wiersz we- wnątrz sekcji head naszej strony internetowej:Meta tag viewport jest powszechnie używany, jako że zastępuje on do- myślny i pomaga załadować styl związany z konkretnym obszarem wyświe- tlania. Właściwość width ustawia szerokość ekranu. Może ona zawierać war- tości numeryczne jak 320, oznaczając 320 pikseli, lub może posiadać wartość 'device-width', która informuje przeglądarkę, aby skorzystać z natywnej rozdzielczości (lub szerokości – dla uproszczenia) urządzenia. Właściwość initial-scale jest początkową skalą obszaru wyświetlania jako mnożnik. Tak więc, gdy jest ustawiona na 1.0, to oznacza wtedy natywną szerokość dla danego urządzenia. Oczywiście, po tym należy dodać responsive CSS z Boot- strap, jak pokazano na poniższym kodzie:Teraz, gdy spojrzymy na plik responsive CSS, możemy zauważyć, że po deklaracji pewnych ogólnych składników (linie ~10 do 22) istnieją wyspecy- fikowane różne sekcje zaczynające się od znacznika '@media'. Mamy tam zdefiniowane style dla różnych wielkości urządzeń:

    MISSION CODE ACHIEVE NEW LEVEL JOIN THE CREW

    16 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA • Pierwsza z tych sekcji rozpoczyna się od znacznika '@media (max- width: 480px)', który określa style dla urządzeń, gdzie maksymalna szerokość jest równa 480 pikseli. • Druga sekcja rozpoczyna się od znacznika '@media (max-width: 767px)', który określa style dla urządzeń, gdzie maksymalna szerokość jest równa 767 pikseli. • Trzecia sekcja rozpoczyna się od znaczników '@media (min-width: 768px) oraz (max-width: 979px)', zapis ten określa style dla urzą- dzeń, których minimalna szerokość wynosi 768 pikseli, a maksymalna szerokość to 979 pikseli. • Następna sekcja jest określona dla urządzeń z maksymalną szeroko- ścią 979 pikseli, więc zaczyna się od znacznika '@media (max-width: 979px)'. • Ostatnie dwie sekcje zaczynają się od znaczników '@media (min- width: 980px)' oraz '@media (min-width: 1200px)', więc są prze- znaczone dla urządzeń o minimalnej szerokości 980 pikseli i 1200 pikseli. Funkcją, jaką spełnia ten arkusz, jest więc przechowywanie stylów według minimalnej i maksymalnej szerokości urządzeń korzystających z właściwości 'min-width' oraz 'max-width'. Aby układ responsive mógł być osiągnię- ty, Twitter Bootstrap wykonuje kolejno trzy rzeczy: 1. Modyfikuje szerokości kolumny w siatce. 2. Ilekroć jest wymagane, używa stosu elementów zamiast elementu pływającego, Element główny (html) tworzy korzeń kontekstu układania. Inne kontek- sty układania są generowane przez umieszczanie kolejnych elementów (w tym elementów pozycjonowanych relatywnie) o wyliczonej wartości 'z-in- dex' innej niż 'auto'. 3. Aby renderować prawidłowo nagłówki i tekst, zmienia ich rozmiary w ra- zie potrzeby. NARZĘDZIARESPONSYWNEWWERSJI3.0.0 W dzisiejszych czasach coraz więcej osób przegląda strony www za pomocą różnych urządzeń mobilnych. Praktycznie każdy nowoczesny telefon czy tablet umożliwia w jakimś stopniu korzystanie z Internetu. Jako projektanci musimy zadbać o to, aby zapewnić takim osobom jak najłatwiejszy dostęp do treści i funkcjonalności witryny. Prawidłowe dostosowanie strony do urządzeń mo- bilnych sprawi, że szerokie grono osób będzie mogło ją wygodnie przeglądać. Projektowanie stron na przeglądarki mobilne nie jest łatwym zadaniem.To zło- żony temat, który obejmuje zarówno aspekty wizualne, jak i funkcjonalne. W celu szybszego rozwoju interfejsów wspierających zastosowania mo- bilne (mobile-friendly), potrzeba korzystać z klas użytkowych służących do pokazywania/ukrywania zawartości poprzez urządzenia, wykorzystując Me- dia Queries. Szybsze rozwijanie takich interfejsów jest możliwe dzięki Twitter Bootstrap, który teraz również posiada zestaw klas użytkowych dla przyśpie- szenia tego procesu. Klasy te są dostępne w module 'responsive-utilities.less'. Należy używać ich w ograniczonym zakresie, unikając tworzenia różnych wersji tej samej witryny (w celu uzupełnienia prezentacji dla każdego urzą- dzenia). Narzędzia responsywne są obecnie dostępne tylko w blokach i w przełączeniu tabeli (block and table toggling). Korzystanie z nich inline oraz jako elementów tabeli nie jest aktualnie obsługiwane. Można wykorzystać jedną klasę lub kombinacji dostępnych klas w celu przełączania zawartości w bieżących wartościach granicznych obszaru wyświetlania. Warto opanować najważniejsze techniki responsywne, czyli takie, które po- zwolą nam dostosować witrynę do różnych urządzeń. Poznać podstawowe zasa- dy tworzenia witryn responsywnych, dowiedzieć się, jak wykorzystać możliwości Media Queries oraz jak stworzyć płynny układ kolumn. Poznać przydatne rozwią- zania, umożliwiające dostosowanie typowych elementów strony, jak: obrazki, tabele oraz menu do mobilnych przeglądarek. Framework Bootstrap oferuje sze- roki zestaw klas i skryptów, które pozwolą łatwo i szybko stworzyć responsywną strukturę witryny, dodać style oraz różne przydatne funkcjonalności. Rysunek 14. Ilustracja obrazująca filozofię Responsive Design

    17/ www.programistamag.pl / TWITTER BOOTSTRAP – SZYBKIE TWORZENIE WITRYN HTML Rysunek 15. Zestawienie klas dla przełączania zawartości bieżącego obszaru wyświetlania w wersji 3.0.0 PODSUMOWANIE W drugiej części artykułu omówiono wybrane ważniejsze (z punktu wi- dzenia developera) komponenty będące składnikami frameworka. Opisano również ważniejsze zmiany występujące w wersji v3.0.0, która jest oficjalną wersją produkcyjną. Twitter Bootstrap obecnie implementuje flat design, co w przypadku stron internetowych nie zawsze jest pożądane. Wystąpiły pew- ne zmiany w nazewnictwie oraz strukturze i teraz nie wszystko, co było do- stępne w v 2.3, jest dostępne także w v3.0.0. Zmiana niektórych nazw klas być może ma sens, ale utrudnia aktualizację do najnowszej wersji. Można pokusić się o ponowną kompilację plików LESS, przywracając poprzednie nazewnic- two, ale będzie to pracochłonne. Podsumowując – dzięki wykorzystaniu bibliotek Bootstrap'a rozwijane aplikacje internetowe tworzone są szybciej, będą się cechowały skalowalno- ścią oraz przyjaznym interfejsem użytkownika. Bezbłędne działanie pakietu jest zagwarantowane przez twórców w przeglądarkach Chrome, Safari oraz Firefox. Można zaznaczyć, że wciąż trwają także prace nad polepszeniem wy- dajności obsługi dla przeglądarki Internet Explorer. Zdobytą wiedzę możemy bez przeszkód zastosować do utworzenia wła- snej witryny oraz poszerzyć swoje umiejętności w zakresie tworzenia este- tycznie wyglądających, responsywnych stron. Dzięki Bootstrapowi proces ten będzie łatwy i przyjemny. Koniec z wyliczaniem marginesów, tworzeniem form czy ramek od podstaw – Twitter Bootstrap zrobi to za nas. Korzystając ze skalowalności, nasza strona będzie dobrze wyglądała na komputerze, ta- blecie czy smartfonie. Wykorzystanie frameworka przy projektowaniu strony przyspieszy nam pracę oraz zwiększy zadowolenie z efektu końcowego. W sieci PP http://twitter.github.com/bootstrap/–zasobyTwitterBootstrapv2.3.2. PP http://themecrunch.com/2013/04/twitter-bootstrap-tutorials-tools- and-resources/ – zasoby oraz tutoriale dlaTwitter Bootstrap. PP http://getbootstrap.com/components/ – dokumentacja dla komponentówTwitter Bootstrap v3.0.0. PP http://getbootstrap.com/css/ – dokumentacja modułu CSS dla Twitter Bootstrap v3.0.0. PP http://getbootstrap.com/javascript/ – dokumentacja JavaScript dla Twitter Bootstrap v3.0.0. PP http://www.bootstraptor.com/bootstrap3 – zestawy szablonów i motywy zbudowane przy wykorzystaniuTwitter Bootstrap v3.0.0. PP http://www.w3resource.com/twitter-bootstrap/responsive-design.php– ResponsiveWebDesignprzywykorzystaniuTwitterBootstrap–artykuł. PP http://getbootstrap.com/customize/ – moduł pobierania frameworka wraz z panelem personalizowania. PP http://getbootstrap.com/getting-started/#migration – ważniejsze zmiany pomiędzy wersjami 2.x a 3.0.0. PP http://bradfrostweb.com/blog/web/mobile-first-responsive-web- design/ – blog traktujący o tematyce Responsive Design Łukasz Mazur lukash.mazur@gmail.com Autor obecnie jest programistą/architektem aplikacji biznesowych dedykowanych na platformy mobilne. Pracuje dla irlandzkiej firmy Mobile Travel Technologies Ltd. Dodatkowo poszerza swoja wiedzę dotyczącą zagadnień analityki biznesowej w Institute of Technology Blanchardstown – Dublin na wydziale Computing Business Intelligence & Data Mining.

    18 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA Karol Rogowski S koro już wiemy, czym są aplikacje czasu rzeczywistego, a jeszcze nie zdążyliśmy przejść do żadnej konkretnej rozmowy technicznej, to zasta- nówmy się, czy faktycznie jest tego aż tak wiele, żeby było warto zaprzą- tać sobie tym głowę. Zacznijmy może od portali społecznościowych, które to ostatnio na całym świecie zdobywają coraz większą popularność. Nie mówię już nawet o kwestiach rozmów, ponieważ konieczność dostawania tam danych na żywo jest kwestią bezdyskusyjną. Zauważmy też, że każda niemalże akcja innych użytkowników mająca z nami jakiś związek skutkuje natychmiastowym poinformowaniem nas o tym. Portale społecznościowe nie są oczywiście jedy- ne, jeżeli chodzi o konieczność posiadania świeżych danych. Spójrzmy na przy- kład na wszelkiego typu notowania. Czy to giełdowe czy też związane z wy- nikami sportowymi. Dodatkowo są też najróżniejsze aplikacje pozwalające na jednoczesną interakcję ze sobą kilku użytkowników.Tak, wiem, że pierwszą na- chodzącą myślą są gry interaktywne, ale to nie jest jedyny przykład. Są przecież też sytuacje, gdy jednocześnie musimy pracować nad jakimś dokumentem. Przykłady tego typu można by mnożyć jeszcze długo. Ale mam nadzieję, że udało mi się już zobrazować skalę problemu posiadania realnych danych oraz to, że naprawdę istnieje szeroki rynek na tego typu rozwiązania. PUSH SERVICE Zanim zaczniemy omawiać konkretne rozwiązanie technologiczne, po- wiedzmy sobie, w jaki sposób odbywa się komunikacja w omawianych apli- kacjach. Bazuje ona na wzorcu zwanym Push Service. I chociaż bardzo się starałem, to nie udało mi się wymyśleć tłumaczenia na polski, które nie wy- paczałoby treści zawartej w oryginalnej nazwie. Dlatego właśnie zostaniemy przy nazwie anglojęzycznej. Push Service, najogólniej mówiąc, ma za zadanie dostarczanie i rozdzielanie komunikatów. Przyjrzyjmy się rysunkowi poniżej, a następnie omówimy dokładniejszą budowę tego wzorca. Rysunek 1. Budowa wzorca Push Service Jak widzimy powyżej Push Service opiera się na synchronizacji współ- pracy podpiętych do niego klientów oraz zdarzeń. Klienci w tym przypadku powinni być rozumiani jako wszelkiego rodzaju aplikacje chcące korzystać z powiadomień dostarczanych przez serwis. Z drugiej strony mamy natomiast zdarzenia, których wystąpienie powoduje wysłanie powiadomień do odpo- wiednich klientów. Natomiast klienci po otrzymaniu powiadomienia już po swojej stronie odpowiednio na nie reagują. Wiem, że na pewno taki schemat nie zobrazuje od razu wszystkiego, ale na pewno da jakiś pogląd na to, co chcemy osiągnąć. SIGNALR Na początku powiedzmy sobie, czym w ogóle jest SignalR. Jest to Frame- work pozwalający nam na tworzenie Push Service-ów. Składa on się z dwóch części. Pierwszą z nich jest zestaw rozwiązań serwerowych, które służą nam do faktycznego budowania tego, w jaki sposób ma wyglądać nasz serwis, oraz z części klienckiej. Odpowiedzialna jest ona za możliwość komunikacji z serwisem. Dzięki odpowiednim bibliotekom pozwala ona na komunikację z praktycznie każdą platformą. Jest to bardzo ważne, ponieważ ciężko jest wy- magać, aby wszystko pracowało na .NET-cie. Ogólna idea działania tej technologii jest poniekąd schowana w jej na- zwie. Chodzi mianowicie o to, że powinniśmy operować na sygnałach. Po- przez sygnał rozumiemy wysłanie małej porcji danych, która zostaje już po stronie odczytującej ją aplikacji odpowiednio zinterpretowana. Powinniśmy się wystrzegać przesyłania przy użyciu SignalR całych dużych kawałków da- nych. Jeżeli chcemy napisać sygnał, który będzie informował o zmianach w którymś z elementów wyświetlanych na naszej stronie, powinno to się odbyć następująco: Sygnał informuje nas o tym, że dany element się zmienił. Może to zrobić na przykład poprzez wysłanie jego identyfikatora. Dopiero nasza aplikacja po odpowiedniej interpretacji sygnału pobiera oddzielnym zapyta- niem nowe dane i obsługuje je na właściwy sposób. NAPISZMY COŚ Jak już pewnie zdążyliście zauważyć, w swoich artykułach staram się kłaść możliwie jak największy nacisk na praktyczne wykorzystanie technologii i w ten sposób zapoznawać Was z jej działaniem. Nie inaczej będzie w tym przypadku. Napiszemy Push Service, który to będzie obsługiwał scenariusz prostego chatu. Nie jest to może jakiś bardzo skomplikowany i wyrafinowa- ny przykład, ale pozwoli zaznajomić się ze sposobem działania omawianej technologii. A jeżeli ktoś będzie chciał dalej się tego uczyć, to będzie miał już gotowe podwaliny. Pierwszym krokiem, jaki należy wykonać, jest utworzenie pustej aplika- cji ASP.NET MVC4, na której będziemy pracować. Kolejną czynnością będzie dodanie do naszego projektu Hub-a. Hub jest to klasa, w której będziemy ASP.NET SignalR – czyli aplikacje czasu bardzo rzeczywistego Aplikacje czasu rzeczywistego to rozwiązania, które dostarczają dane na bieżąco. Powiedzmy na przykład, że chcemy przeczytać sobie poranne wiadomości na którymś z licznych istniejących w sieci portali. Dane powinny tam być możliwie świeże, z tym że nie są one raczej dostarczane na żywo, a po prostu pobierają się podczas naszego wej- ścia na stronę. Wszystko w tej sytuacji jest ok, ponieważ nie oczekujemy chyba odświe- żania ich co chwilę. Inaczej sytuacja wygląda, jeżeli chodzi np. o chat na jakimś portalu społecznościowym. Tutaj otrzymywanie danych na żywo jest kwestią krytyczną.

    19/ www.programistamag.pl / ASP.NET SIGNALR – CZYLI APLIKACJE CZASU BARDZO RZECZYWISTEGO definiować zachowania naszego serwisu. Będą się tam znajdować zarówno wymagane zdarzenie, jak i te metody, które są charakterystyczne tylko dla naszego rozwiązania. Klasę taką możemy dodać, jako jeden z już przygoto- wanych elementów. Rysunek 2. Dodawanie nowego Hub-a Po kliknięciu przycisku Add do naszego projektu zostanie dodany nowy element. Oprócz tego, że widzimy teraz nowy plik, to warto zwrócić uwagę na trzy nowe referencje, które pojawiły się w naszym rozwiązaniu. Są to bibliote- ki Microsoft.AspNet.SignalR.Core, Microsoft.AspNet.SignalR.Owin oraz Micro- soft.AspNet.SignalR.SystemWeb. Jak łatwo można zgadnąć, są to elementy odpowiedzialne za działanie technologii SignalR w naszej aplikacji. Zajrzyjmy teraz do naszego nowego pliku. Listing 1. Zawartość pliku ChatHub.cs namespace ExampleChat { using Microsoft.AspNet.SignalR; ///

    /// Klasa huba naszego projektu /// public class ChatHub : Hub { public void Hello() { Clients.All.hello(); } } } Widzimy, że nowoutworzona klasa ma tak naprawdę bardzo prostą budo- wę. Jedynym elementem, na jaki należy w tym momencie zwrócić uwagę, jest jej dziedziczenie po klasie Hub. Co z tego dziedziczenia wynika, zobaczymy już za chwilę. Zanim jednak przejdziemy do implementacji funkcjonalności, musimy poinformować aplikację, że będzie ona korzystała z hub-ów. Robimy to pod- czas zdarzenia startu aplikacji. Możemy oczywiście znaleźć je w pliku Global. asax. Zarejestrowanie hub-ów musi odbyć się od razu po wywołaniu akcji RegisterAllAreas(). Jest to bardzo ważne, ponieważ w przeciwnym wy- padku nasze rozwiązanie w ogóle nie zadziała. Listing 2. Prawidłowa rejestracja Hub-ów w pliku Global.asax public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteTable.Routes.MapHubs(); WebApiConfig.Register(GlobalConfiguration. Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters. Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); } } Skoro nasza aplikacja już wie, że ma korzystać z hub-ów, zastanów się te- raz, jakie w ogóle funkcjonalności chcemy zaimplementować. Po pierwsze, musi być możliwość wysyłania wiadomości. Fajnie też by było móc nadać sobie jakieś imię. Funckjonalnością jakby oczywistą jest możliwość otrzymy- wania informacji. Jako bonus dajmy naszemu rozwiązaniu odrobinę prywat- ności. Powiedzmy, że damy użytkownikom możliwość spotykaniu się w poko- jach i rozmawiania tylko wewnątrz nich. To byłoby chyba na tyle, jeżeli chodzi o opcje. Jeśli jeszcze jakaś nasunie się w trakcie, to będziemy uzupełniać tę listę na bieżąco. Wszystkie te zdarzenia należy zakodować oczywiście w naszym Hub-ie. Może zróbmy to w ten sposób, że zaprezentuję od razu gotowy i, wydaje mi się, dość czytelnie okomentowany kod, a następnie będę omawiał kolejne elementy i w ten sposób tłumaczył, co tam się dzieje. Listing 3. Zaprogramowana klasa Hub-a /// /// Klasa Hub-a naszego chat-u /// [HubName("ExampleChat")] public class ChatHub : Hub { /// /// Metoda pozwalająca na wysłanie wiadoności do wszystkich użytkowników /// /// Nazwa użytkownika/// Treść wiadomościpublic void SendMessage(string name, string message) { var msg = string.Format("{0}: {1}", name, message); Clients.All.newMessage(msg); } /// /// Metoda pozwalająca na połączenie to jakiegoś pokoju /// /// Nazwa użytkownika/// Nazwa pojoku to którego chcemy podączyćpublic void JoinRoom(string name, string room) { Groups.Add(Context.ConnectionId, room); var msg = string.Format("{0} joined room: {1}", name, room); Clients.Group(room).newMessage(msg); } /// /// Metoda pozwalająca na wysłanie wiadoności do użytkowników w danym pokoju /// /// Nazwa użytkownika/// Nazwa pokoju/// Treść wiadomościpublic void SendMessageToRoom(string name, string room, string message) { var msg = string.Format("{0}: {1}", name, message); Clients.Group(room).newMessage(msg); } /// /// Nadpisane zdarzenie na łączenie się z Hub-em /// /// Obiekt odpowiedni dla metody którą nadpisujepublic override Task OnConnected() { this.SendMonitoringData("Połączono", Context. ConnectionId);

    20 / 10 . 2013 . (17)  / BIBLIOTEKI I NARZĘDZIA return base.OnConnected(); } ///

    /// Nadpisane zdarzenie na rozłączenie się z Hub-em /// /// Obiekt odpowiedni dla metody którą nadpisujepublic override Task OnDisconnected() { this.SendMonitoringData("Rozłączono", Context. ConnectionId); return base.OnDisconnected(); } /// /// Nadpisane zdarzenie na ponowne połączenie się z Hub-em /// /// Obiekt odpowiedni dla metody którą nadpisujepublic override Task OnReconnected() { this.SendMonitoringData("Połączono ponownie", Context.ConnectionId); return base.OnReconnected(); } /// /// Metoda pozwalająca na informaowanie użytkowników o zdarzeniach występujących na Hub-ie /// /// Rodzaj zdarzenia/// Identyfikator połączenie które wywołało to zdarzenieprivate void SendMonitoringData(string eventType, string connection) { Clients.All.newEvent(eventType, connection); } } Tak jak obiecałem, tak też teraz zrobię. Skoro każdy już przeczytał zapre- zentowany kod, możemy przejść do szczegółowego omawiania go. Pierw- szym elementem, jaki rzuca nam się w oczy, jest atrybut HubName; pozwala on na ustawienie nazwy naszego Hub-a. Do czego konkretnie może się to przydać, zobaczymy w kolejnym listingu. W pełni natomiast zrozumiemy to podczas kolejnego artykułu, gdy będziemy pisać klientów rozmawiających na czacie. Pierwszą publiczną metodą jest SendMessage. Pozwala ona na wysłanie wiadomości do wszystkich podłączonych klientów. Właśnie w tym momen- cie chciałbym, abyśmy zobaczyli, jak wygląda komunikacja z klientami. Po pierwsze, omawiana właśnie metoda musi być wywołana przez klienta. Jak on to robi, będzie wyjaśnione w kolejnej części artykułu. W tym momencie in- teresuje nas kontakt od serwera do klienta. W tym przypadku chcemy wysłać sygnał do wszystkich klientów. Dlatego właśnie z obiektu Clients skorzystali- śmy z właściwości All, która to oczywiście zwraca nam wszystkich klientów. Następnie już sami, bez żadnych podpowiedzi, definiujemy metodę oraz pa- rametry, które zostaną wysłane do klientów ze zbioru All. Kolejną metodą jest JoinRoom.Tak jak już mówliśmy, każdy potrzebuje czasami odrobiny prywat- ności. Dlatego właśnie SignalR oferuje nam możliwość wysyłania sygnałów tylko do klientów będących w pewnej grupie. Właśnie za to odpowiada nasza metoda. Na początku widzimy kod, który dodaje identyfikator połączenia, z którego została wywołana ta metoda do pokoju o nazwie przekazanej para- metrem. Na końcu, tak jak poprzednio, wysyłamy wiadomość do odpowied- nich klientów. Z tym, że tym razem nie są to już wszyscy klienci, a jedynie ci należący do tego pokoju (do tej grupy). Zrobiliśmy to poprzez wywołanie na obiekcie Clients metody Group, zamiast właściwości All. Kolejna przedsta- wiona metoda daje nam możliwość wysłania wiadomości tylko do klientów z danej grupy. Nie ma tu żadnych nowych konstrukcji, jeżeli chodzi o kod, nie będziemy więc się na niej zatrzymywać. Kolejne trzy kroki będzie stanowić nadpisanie zdarzeń z klasy bazowej. Jest to bardzo charakterystyczne zachowanie, jeżeli chodzi o programowanie obiektowe, dlatego też, jeżeli ktoś ma problem ze zrozumieniem tej części kodu, to zachęcam do douczenia się. Wiedza ta na pewno się przyda. Co do zawartości tych metod, to każda z nich zawiera odwołanie do metody, która to ma monitorować aktywności na naszym Hub-ie. Następnie oczywiście wy- wołujemy nadpisane zdarzenie z klasy bazowej, dzięki czemu działanie naszej aplikacji nie zostanie zachwiane. Ostatnim elementem stworzonym w klasie jest metoda pozwalająca na obronienie monitorowanych akcji. W przypadku realnej aplikacji w tym miej- scu znajdowałby się prawdopodobnie kod w jakiś sposób monitorujący za- chodzące zdarzenie. Jako że jest to aplikacja demonstracyjna, to będziemy po prostu wysyłać informacje o zdarzeniach do wszystkich podłączonych klientów. Skoro mamy już wszystko przygotowane, to uruchommy naszą aplikację i zobaczmy, co się stanie. Chwila napięcia…. No i nie stało się nic, a na pewno nic pozytywnego. Otrzymaliśmy ekran błędu mówiący, że poszukiwane zasoby nie zostały odnalezione. Nie ma czym się martwić, bo ten ekran jest dokładnie tym, co powinniśmy w tym momen- cie widzieć. Zastanówmy się, co tak naprawdę oczekiwaliśmy, że zobaczymy. Jakiś napis typu:„Nie masz żadnych kontrolerów ani widoków, ale nie martw się, wszystko na pewno działa”? Niestety nie jest tak pięknie. Rysunek 3.Widok aplikacji po uruchomieniu Skoro teraz widzimy błąd, to pozostaje pytanie, jak sprawdzić, czy apli- kacja faktycznie działa. Dla nas działanie aplikacji oznacza ni mniej ni więcej niż to, że działa nasz Hub-a. Możemy to sprawdzić pod poniższym adresem: http://localhost:58033/signalr/hubs. Jeżeli wszystko zaprogramowaliśmy po- prawnie, to powinniśmy zobaczyć w ekranie przeglądarki kod Hub-a, którego w trakcie artykułu stworzyliśmy. Listing 4. Kod działającego Hub-a /*! * ASP.NET SignalR JavaScript Library v1.0.0 * http://signalr.net/ * * Copyright Microsoft Open Technologies, Inc. All rights reserved. * Licensed under the Apache 2.0 * https://github.com/SignalR/SignalR/blob/master/LICENSE.md * */ /// /// (function ($, window) { if (typeof ($.signalR) !== "function") { throw new Error("SignalR: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/ signalr/hubs."); } var signalR = $.signalR; function makeProxyCallback(hub, callback) { return function () { // Call the client hub method callback.apply(hub, $.makeArray(arguments)); }; } $.hubConnection.prototype.createHubProxies = function () {

    21/ www.programistamag.pl / ASP.NET SIGNALR – CZYLI APLIKACJE CZASU BARDZO RZECZYWISTEGO reklama var proxies = {}; this.starting(function () { // Register the hub proxies as subscribed // (instance, shouldSubscribe) registerHubProxies(proxies, true); this._registerSubscribedHubs(); }).disconnected(function () { // Unsubscribe all hub proxies when we "disconnect". This is to ensure that we do not re-add functional call backs. // (instance, shouldSubscribe) registerHubProxies(proxies, false); }); proxies.ExampleChat = this.createHubProxy('ExampleChat'); proxies.ExampleChat.client = {}; proxies.ExampleChat.server = { joinRoom: function (name, room) { return proxies.ExampleChat.invoke.apply(proxies. ExampleChat, $.merge(["JoinRoom"], $.makeArray(arguments))); }, sendMessage: function (name, message) { return proxies.ExampleChat.invoke.apply(proxies. ExampleChat, $.merge(["SendMessage"], $.makeArray(arguments))); }, sendMessageToRoom: function (name, room, message) { return proxies.ExampleChat.invoke.apply(proxies. ExampleChat, $.merge(["SendMessageToRoom"], $.makeArray(arguments))); } }; return proxies; }; signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false }); $.extend(signalR, signalR.hub.createHubProxies()); }(window.jQuery, window)); Powyżej nie został oczywiście przedstawiony cały zawarty tam kod. Jedy- nie elementy, na które chciałbym zwrócić uwagę. Na początku uświadommy sobie, co tak naprawdę się tutaj znajduje. Jest to samo-wywołująca się funk- cja (javascript self invoking function). Zamieszczam angielską nazwę z dwóch względów. Po pierwsze, tłumaczenie na polski niektórych nazw technicznych wychodzi strasznie, i to jest zdecydowanie jeden z takich przypadków. Po dru- gie, jeżeli ktoś nie rozumie, jak to działa, to bez problemu będzie wiedział, czego szukać w Internecie. Co do wewnętrznej budowy kodu, to spójrzmy na dwa miejsca. Po pierw- sze, na funkcję createHubProxy.W jej argumencie jest podana nazwa, którą to narzuciliśmy naszemu Hub-owi. Po drugie, na to, gdzie znajdują się napisa- ne przez nas metody. Zostały one zamknięte w obiekcie, jako wartości unikal- nych kluczy, a obiekt ten jest przypisany do Proxy naszego Hub-a. Jak łatwo można było się domyśleć, wszystkie one zostały jak najbardziej prawidłowo uznane za metody serwerowe. Na koniec tego artykułu mam jeszcze prośbę, aby każdy przeanalizował sobie resztę kodu Hub-a. Można dzięki temu zdobyć sporo ciekawej wiedzy na temat szczegółów jego działania. PODSUMOWANIE Artykuł ten był pierwszą z dwóch części omawiania technologii SignalR. Dowiedzieliśmy się, czym w ogóle są aplikacje czasu rzeczywistego, na jakiej zasadzie działają oraz jak omawiana technologia odpowiada na ten sektor potrzeb. Jeżeli chodzi o praktykę, to stworzyliśmy część serwerową naszego rozwiązania, z którą będziemy, jako klienci, łączyć się w następnym artykule. Ja ze swojej strony bardzo dziękuję za czas poświęcony na przeczytanie tego artykułu i zapraszam do lektury kolejnych. W przypadku jakichkolwiek uwag,pytańlubpropozycjipomysłównakolejneartykułyproszępisaćnakarol. rogowski@gmail.com lub szukać mnie na https://twitter.com/KarolRogowski. Karol Rogowski karol.rogowski@gmail.com Absolwent Informatyki Politechniki Białostockiej. Microsoft Certificated Professional Deve- loper .NET Web Developer. Obecnie pracuje jako Development Lead w firmie DevCore.Net. Autor wielu treści na portalach technologicznych, głównie związanych z HTML 5 i JavaScript. W wolnym czasie pokerzysta amator

    22 / 10 . 2013 . (17)  / PROGRAMOWANIE APLIKACJI WEBOWYCH Michał Leszczyński N ajpopularniejszą metodą logowania w Internecie jest uwierzytel- nianie za pomocą hasła. Metoda ta, choć jest jedną z najwygod- niejszych, nie jest pozbawiona wad. W celach porównawczych na serwerze muszą być przechowywane hasła wszystkich użytkowników – naj- częściej w formie hasha, np. z funkcji SHA1, bcrypt etc. W przypadku wycie- ku bazy danych będącego choćby następstwem włamania, atakujący może posłużyć się różnymi technikami, aby odzyskać oryginalne hasła, inwestując w to odpowiednią ilość mocy obliczeniowej. Istnieje też ryzyko wstawienia przez włamywacza backdoora w kodzie aplikacji, który zajmie się rejestro- waniem haseł przesyłanych na serwer otwartym tekstem podczas logowa- nia (ruch HTTPS trafiający do aplikacji zostaje już wcześniej odszyfrowany przez serwer). Odporność na tego typu zagrożenia wykazuje autoryzacja przy pomo- cy certyfikatu użytkownika SSL, podczas której na serwer nigdy nie jest wysyłany pełny certyfikat, a jedynie dowód na to, że użytkownik, który go prezentuje, jest równocześnie jego właścicielem. Jest to możliwe dzię- ki zastosowaniu kryptografii asymetrycznej. Po stronie serwera nie trzeba więc przechowywać żadnych wrażliwych danych logowania dotyczących konkretnych użytkowników. Bezpieczeństwo całego systemu przekłada się bezpośrednio na bezpieczeństwo klucza używanego do wystawiania certyfikatów. Podpis cyfrowy Algorytmy szyfrowania asymetrycznego, oprócz swojego typowego za- stosowania w szyfrowaniu wiadomości, znajdują użycie przy tworzeniu pod- pisów cyfrowych. Para kluczy dla szyfru asymetrycznego składa się z dwóch kluczy: prywatnego (który należy do właściciela i powinien być przecho- wywany bezpiecznie) oraz publicznego. Dowolna wiadomość może zostać podpisana cyfrowo przez posiadacza klucza prywatnego, a wiarygodność podpisu można zweryfikować, wykorzystując klucz publiczny. SPOSÓB DZIAŁANIA Wystawianie certyfikatów Certyfikaty SSL użytkownika mogą być wydawane przez określony urząd certyfikacji (CA), który posiada swój certyfikat główny i jest uznany za zaufa- ny na serwerze aplikacji. Ponieważ certyfikaty użytkownika są wystawiane w celu umożliwienia serwerowi sprawdzenia tożsamości klienta, a nie odwrot- nie jak w przypadku klasycznego zastosowania SSL, certyfikat główny nie musi być zainstalowany w systemie klienta. Certyfikaty użytkownika SSL – jak to ugryźć? Technologia SSL znajduje swoje użycie w olbrzymiej ilości aplikacji i usług interne- towych. Jednym z głównych celów jej zastosowania jest umożliwienie klientowi sprawdzenie, czy komunikuje się on z zaufanym serwerem. Istnieje jednak rozsze- rzenie, które pozwala dokonać zupełnie odwrotnej czynności, umożliwiając serwe- rowi sprawdzenie autentyczności klienta. Celem tego artykułu jest zatem omówie- nie i implementacja certyfikatów użytkownika na przykładzie aplikacji hostowanej w kontenerze Tomcat. Rysunek 1. Procedura wystawiania certyfikatów użytkownika SSL Distinguished name CertyfikatyużytkownikasązgodnezestandardemX.509(RFC5280 [1] ), muszą więc zawierać distinguished name (DN) podmiotu oraz wystawcy, czyli informacje o nich zapisane w formacie par atrybut=wartość, od- dzielanych przecinkiem. Przykładowy DN podmiotu: CN=someguy123, O=Example Flail Store, OU=Member Najczęściej używane standardowe atrybuty: O organization name OU organizational unit name CN common name L locality name ST state or province C country name Uwierzytelnianie użytkownika Autoryzacja użytkownika za pomocą certyfikatu jest opcjonalną częścią SSL handshake, czyli negocjacji bezpiecznego połączenia z serwerem. Należy tu zauważyć, że przeprowadzenie takiej autoryzacji nie jest możliwe w połą- czeniu nieszyfrowanym. Podczas uwierzytelniania certyfikatem użytkownika, losowe dane wy- generowane podczas negocjacji bezpiecznego połączenia są podpisywane przez użytkownika za pomocą wcześniej wystawionego mu certyfikatu. Pod- pis ten jest później wysyłany wraz z informacjami o certyfikacie do serwera.

    24 / 10 . 2013 . (17)  / PROGRAMOWANIE APLIKACJI WEBOWYCH Do tagu Connector odnoszącego się do connectora HTTPS należy dodać następujące atrybuty: truststoreFile="" truststorePass="" clientAuth="want|true" Atrybut clientAuth określa zachowanie serwera podczas negocjacji bez- piecznego połączenia. Jeśli wartość atrybutu zostanie ustawiona na want, ser- wer będzie honorował certyfikaty użytkownika, ale pozwoli również ustanowić połączenie klientom, którzy z jakiegoś powodu nie mogą przedstawić prawi- dłowego certyfikatu. W przypadku ustawienia wartości na true, serwer każ- dorazowo będzie zrywał połączenia od klientów, którzy się nie uwierzytelnią. CLIENT-SIDE: GENEROWANIE ŻĄDAŃ CERTYFIKACJI Z PRZEGLĄDARKI Do bezpiecznego przeprowadzenia certyfikacji potrzebne jest API, któ- re pozwoli na wygenerowanie pary kluczy i stworzenie żądania certyfikacji (CSR). Przeglądarki kompatybilne z Netscape (Firefox, Chrome, etc.) oferują do tego celu tag keygen [3] będący regularnym elementem formularza. Mi- crosoft odmówił jednak implementacji tego rozwiązania w Internet Explorer, ponieważ w systemach Windows Vista i nowszych dostępne jest Certificate Enrollment API [4] , którego można użyć przez ActiveX z poziomu skryptu po stronie klienta. Wobec tego, trzeba stworzyć aplikację, która zależnie od przeglądarki klienta zaserwuje mu formularz wykorzystujący kompatybilną technologię. Ze względu na ograniczoną ilość miejsca, implementacja omówiona w arty- kule będzie dosyć uproszczona, aby nie zagłębiać się w rzeczy mocno wykra- czające poza temat. Po stronie klienta przykład ograniczy się do dwóch statycznych stron z formularzami – jednym dla IE, drugim dla przeglądarek kompatybilnych z Netscape. Oba formularze będą zawierały pole do wpisania nicku, który zo- stanie później użyty jako Common Name (CN) w wygenerowanym certyfika- cie, oraz kontrolkę generatora kluczy. Keygen Element reprezentuje generator pary kluczy i jest wyświe- tlany w przeglądarce analogicznie do tagu
    Przy próbie wysłania formularza żądanie certyfikacji zostanie automa- tycznie wygenerowane i wstawione jako parametr csr. W odpowiedzi na to zapytanie, serwer powinien wysłać wystawiony certyfikat wraz z nagłówkiem Content-Type: application/x-x509-user-cert Przeglądarka automatycznie zainstaluje taki certyfikat w swoim magazynie. CertEnroll Certificate Enrollment API to rozbudowany interfejs od Microsoft, który pozwala również na wystawianie żądań certyfikacji w formacie PKCS#10 oraz instalowanie wygenerowanego certyfikatu na kompu- terze klienta. Poprzez ActiveX z interfejsu można skorzystać za pomocą X509EnrollmentWebClassFactory[5] . Należy jednak pamiętać, że przeglądarka ze względów bezpieczeństwa nie pozwoli odwołać się do tego obiektu, jeśli strona z korzystającym z niego skryptem nie została po- brana przez HTTPS. Pora na stworzenie formularza dla IE (plik ie.html). Pożądane byłoby, aby oba formularze miały podobny układ i wygląd. Wygląd tagu moż- na emulować, używając
    W tym wypadku żądanie certyfikacji nie zostanie wygenerowane automa- tycznie przy wysyłaniu formularza, cały proces trzeba przeprowadzić, tworząc odpowiedni skrypt JavaScript. Konieczne jest w tym miejscu zadeklarowanie obiektu fabryki, który posłuży do tworzenia potrzebnych obiektów CertEn- roll. Do obsługi odpowiedzi serwera przyda się również jQuery. Listing 3. Potrzebne zależności oraz funkcja pomocniczaOstatnim krokiem jest zdefiniowanie funkcji CreateReq(), która przy wysyłaniu formularza sprawdzi, jakiego wyboru co do długości klucza doko- nał użytkownik, wygeneruje żądanie certyfikacji i wstawi je do pola csr w formularzu. Ponieważ instalacja certyfikatu również wymaga wywołania od- wołania do obiektu Enroll, najwygodniejszym rozwiązaniem będzie wysła- nie zawartości formularza AJAXem, a potem wywołanie Enroll.Install- Response na otrzymanej odpowiedzi, co spowoduje instalację certyfikatu. Listing 4. Funkcja obsługująca wysłanie formularza function CreateReq() { try { var PrivKey = CreateInst("CX509PrivateKey"); var Req = CreateInst("CX509CertificateRequestPkcs10"); var Enroll = CreateInst("CX509Enrollment"); // niezbędne stałe var ALLOW_UNTRUSTED_ROOT = 4; var AT_KEYEXCHANGE = 1; var CONTEXT_USER = 1; var XCN_CRYPT_STRING_BASE64 = 1; var XCN_CRYPT_STRING_BINARY = 2; // rozmiar klucza zgodnie z wyborem użytkownika PrivKey.Length = $("#keysize").val(); PrivKey.KeySpec = AT_KEYEXCHANGE; Req.InitializeFromPrivateKey(CONTEXT_USER, PrivKey, ""); // wystawiamy żądanie certyfikacji PKCS#10 Enroll.InitializeFromRequest(Req); var pkcs10 = Enroll.CreateRequest(XCN_CRYPT_STRING_BASE64); $("#csr").val(pkcs10); $.post({ url: "certHandler", data: $("#csrForm").serialize(), async: false, success: function(data) { Enroll.InstallResponse(ALLOW_UNTRUSTED_ROOT, data, XCN_CRYPT_STRING_BINARY, ""); alert("Zainstalowano certyfikat!"); } }); } catch(ex) { alert("Błąd: " + ex.description); } return false; } Należy zwrócić szczególną uwagę na fakt, że żądania PKCS#10 mogą nieść ze sobą DN podmiotu tworzącego żądanie. Nie ma jednak obowiązku dołączania tej informacji do żądania certyfikacji, a niekiedy wystawiający cer- tyfikat może całkowicie ją zignorować i w odpowiedzi wystawić certyfikat o zupełnie innych parametrach. XEnroll W systemieWindowsXP wprowadzono interfejs XEnroll, który później zo- stał zdeprecjonowany i usunięty w następnej wersji.Z powodu złamania kom- patybilnościwstecznejniejestmożliweużycieXEnrollwsystemieinnymniżXP, alerównieżniejestmożliweużycieCertEnrollwsystemiestarszymniżVista. Server-side: Servlet wystawiający certyfikaty Zadaniem do zrealizowania po stronie serwera jest odbieranie żądań certyfikacji i wystawianie certyfikatów użytkownika. Te czynności będzie re- alizował CertReqHandlerServlet, zmapowany pod URL /csrHandler (adres docelowy dwóch wcześniej stworzonych formularzy). Ponadto, do manipulowania obiektami związanymi z certyfikatami wykorzystana zosta- nie biblioteka BouncyCastle Crypto API [6] (należy dodać do zależności pakiety bcpkix-jdk15on oraz bcprov-jdk15on). Do wystawienia jakiegokolwiek certyfikatu potrzebny jest wcześniej stworzony certyfikat CA. Servlet zaimportuje ten certyfikat wraz z jego klu- czem podczas inicjalizacji.