Czasem dostępność java skryptu powoduje, że w zapomnienie mogą odejść pewne funkcjonalności MVC. W moim przypadku było tak gdy chciałem wyświetlać zawartość kanału z wiadomościami. Klik na kanale, a w tle myk-myk leci ajax i wracają wiadomości. Zrobiłem pewne zmiany w kodzie, tak że teraz kliknięcie na kanale powoduje przeładowanie strony i dopiero teraz użytkownikowi pokazują się wiadomości. Co za tym idzie lista kanałów renderowana jest w dwóch miejscach: na głównej liście, gdy żaden z kanałów nie jest wybrany oraz gdy jeden jest wybrany i czytany.
Jak wyświetlić listę kanałów tu i tu? Początkowa opcja ^c+^v odpada, bo nie. Potem myślę o jakimś ajaxie, jak by to zrobić… Continue reading →
Wszyscy którym brakuje zmysłu artystycznego (ja) korzystają z bootstrapa. Jest on łatwo dostępny (nuget), przyjazny w korzystaniu, w zasadzie każdy nowy projekt tworzony w VS posiada bootstrapa już zainstalowanego i zintegrowanego.
Font awesome
Dla części z nas ikono-grafika dostępna w bootstrapie nie jest wystarczająca sięgamy dalej. Tym dalej, które jest bardzo blisko, jest font awesome:
Coś co bardzo tanim kosztem (0$) oferuje odrobinę artystycznego szaleństwa. Instalacja jest banalnie prosto idziesz to nugeta, wpisujesz font awesome i czekasz …awesome …font …fontawesome … – szieeeet – nie ma. Twoja mać! Trzeba samemu (leń protestuje). Lekko poirytowany ściągasz zipa, rozpakowujesz i co? css, less, scss, fonts i help-us-out.txt.
Klasyczne rozwiązanie to skopiowanie do content. Ale co? Ale które? Continue reading →
Nie raz i nie dwa zdarzało mi się mieć potrzebę posiadania więcej niż jednego guzika na formie. Zawsze ale to zawsze miałem problem z tym jak to dobrze rozegrać. Aż wreszcie trafiłem na dobrą odpowiedź na SO. Continue reading →
Jeśli nie chcesz swojej zguby, nie wrzucaj do repozytorium sekretów swojej aplikacji. Można to osiągnąć w kilku prostych krokach, wystarczy że stworzysz w VS osobny plik z konfiguracją np. “secrets.config“, który może wyglądać tak:
Następnie zaciągniesz go w głównym web.configu w taki sposób:
W VS należy mieć go dodanego do projektu, właściwości ustawione powinny być na content i no-copy, tak samo jak w przypadku web.config. Od teraz zawartość secrets będzie wstrzykiwany do web.config podczas uruchomienia.
Jeszcze tylko w gicie warto dodać go do ignorowanych plików i można spokojnie wrzucać kod na serwer bez potrzeby pamiętania, aby zawsze odznaczyć secrets.config z listy plików.
Natomiast warto pamiętać, aby po każdej zmianie zrobić sobie backup. Tak aby nie stracić go przez przypadek.
Następny wpis, tym razem już na nowym systemie i nowej własnej domenie. Zobaczymy czy będzie tak jak z samochodami, gdzie wizyta na myjni daje dwa konie mechaniczne więcej. Ostatnio pisałem więcej filozoficznie, dzisiaj powrót do twardej rzeczywistości.
Obejrzałem nie dawno na pluralsightfajny i krótki kurs o OWIN i Katana i częścią wiedzy chce się z wami podzielić.
Kto z was zaczynał projekt ASP MVC z włączonymi indywidualnymi kontami użytkowników? Ja na pewno! Także ja, gdy patrzyłem co się dzieje w OWINIE (w części konfiguracyjnej) i AccoutController łapałem się za głowę i zastanawiałem się WTF? Oczywiście próbowałem zrozumieć o co tam chodzi i czemu to wszystko jest tak “fajnie” napisane, niestety nie starczyło mi na to nigdy cierpliwości. Koniec końców pogodziłem się z tym faktem i korzystałem z tego tak jak jest, działało a ja nie zadawałem pytań – sprzedawać!
Teraz to wszystko może się zmienić! (dramatyczna muzyka i suspens – teraz!)
Aby to wszystko zrozumieć, zacząć należałoby od stworzenia pustego projektu MVC5 (tak, wiem staroć) – żadnych dodatkowych referencji, nic! Jak się bawić to na trylion procent. Na koniec wpisu, znajdziecie link do całego projektu. Dodajemy samodzielnie referencje do OWINowych rzeczy, tak aby moje i wasze referencje w tej kwestii się zgadzały:
Microsoft.Owin
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security
Microsoft.Owin.Security.Cookies
Microsoft.Owin.Security.Facebook
Microsoft.Owin.Security.Google
Microsoft.Owin.Security.Twitter
Z racji tego że projekt będzie oparty o MVC, nie można zapomnieć o:
System.Web.Mvc
Kompletna lista referencji w projekcie
Gdy to mamy ogarnięte, warto dodać plik z punktem wejścia do aplikacji, wykorzystany zostanie także do konfiguracji facebooka, twittera czy G+ oraz ogólnej authentykacji, u mnie wygląda on tak:
Co tam ciekawego? Na początku (@14) informujemy aplikację, o chęci korzystania z autentykacji opartej o ciastka. Ciastko przenosząca tajne dane nazywamy ThisCanBeAnythingYouLike. Następnie (@20-@41) wpinamy kolejne warstwy umożliwiające użytkownikom logowanie się przy pomocy FB, Twittera czy G+. Należy podać sekretne kody jednoznacznie identyfikujące waszą aplikacje.
Uwaga (@32) tutaj null oznacza, że nie interesuje mnie walidacja certyfikatów Twittera, oznacza to nie mniej, nie więcej, że jeśli ktoś podszyje się do Twittera i sprzeda mi swój certyfikat, ja to łyknę jak młody pelikan. Taka zagrywka przejdzie na blogu. Na żywej produkcji, należy odnaleźć aktualnie używane certyfikaty Twittera i dodać jest do walidacji. Dodatkowo zwracam uwagę, że wszystkie formy authentykacji korzystają z tego samego ciastka, znowu na blogu nie robi mi to różnicy skąd i jak i czym logują się moi użytkownicy. Produkcja rządzić może się swoimi prawami.
“/Auth/Login” (@14) ta linijka mówi, gdzie należy się przekierować gdy użytkownik nie będzie zalogowany, a aplikacje będzie tego wymagać.
Dla przypomnienia odpowiednio atrybuty AllowAnonymousAttribute oraz AuthorizeAttribute.
Skoro już powiedziałem o przekierowaniu do “/Auth/Login” (Auth controller, Login action) zajrzyjmy co kryje się w tej klasie:
Wielkiej ilości kodu nie ma (gdzie jest AccountController?!). Zaczynając od metody [HttpGet]Login (@15) tworzymy prosty pusty model do logowania się użytkownika. Z OWINa wyciągamy informacje o zarejestrowanych providerach (dostarczycielach?) logowania i wpychamy do modułu, który potem renderujemy.
W parach pracuje się lepiej, dlatego istnieje także [HttpPost]Login (@29) który przyjmuje ten sam model(pamiętamy, że to tylko wpis na blogu i nie maiłczymy że model!=dto!=viewmodel). W klasie są informacje o nazwie i haśle, następuje skomplikowana weryfikacja i jeśli dane są poprawne tworzymy w locie użytkownika. Nadajemy mu także pewne cechy: nazwę oraz identyfikator. Tak zdefiniowanego użytkownika logujemy przy wykorzystaniu OWINa. I wracamy do domu, jeśli weryfikacja się nie powiedzie, dajemy kolejną szansę.
Dla znudzonych oferujemy opcję wylogowania (@47) jak zawsze wszystko kręci się wokół OWINa.
Wreszcie! WRESZCIE! Jak zobaczycie zaraz na przykładzie z razora, tutaj obsługujemy kliknięcie użytkownika, gdy wybierze ono (!on i !ona) opcję logowania się przy pomocy FB, Twitter czy G+. Jako parametr wejściowy przyjdzie nazwa providera. Następnie na OWINie i autentykacji wywołujemy metodę Challange z parametrem informującym, że chcemy wrócić do “/secret”. Kod tego kontrolera pokaże na końcu. Po wywołaniu zwracamy jeszcze odpowiedni kod HTTP aby wszystkim formalnościom stało się zadość. Status Unauthorized jest bardzo ważny i nie może zostać pominięty.
No dobrze, skoro tutaj tak mało kodu, to pewnie razor będzie przekombinowany, pomyślało teraz ono. Aby nie trzymać w niepewności:
Pierwsze linie wynikają z braku pełnej integracji z MVC, odpowiednich wpisów w web.config etc. Ignoruj. Linie (@15-@30) to forma gdzie można się zalogować jako aplikacyjny użytkownik. Linie (@32-@37) to pętla, która wyciąga z modelu (ono przypomina sobie teraz AuthController::Login) listę providerów, na jej podstawie tworzy proste linki z nazwą providera oraz odpowiednim id (“Facebook”, “Twitter”, “Google”), które zostanie przekazane do metody SocialLogin (AuthController::SocialLogin) i użyte to rozróżnienia providera.
Co teraz? Gdzie jest reszta, gdzie jest ACCOUNTCONTROLLER? Nie ma i nie potrzeba. Póki co, nie będę nigdzie zapisywać użytkowników. Demo pokazuje tylko jak zalogować się przy pomocy providerów wymienionych powyżej.
Co znaczy zalogowanie? Otóż mniej więcej tyle:
Będziemy w stanie przejść do metody Index, która jest klasie wymagającej autoryzacji. Czyli User.Identity.IsAuthenticated zwróci TRUE. To całkiem fajnie. Oprócz tego, mamy kilka dodatkowych informacji:
Oraz widok:
W widoku widać że interesują nas cechy nadane nam przez system. Nie ważne czy to FB, Twitter, G+ czy my sami (AuthController, Login w wersji POST). Po uruchomieniu aplikacji wynik operacji wyglądają tak:
Itp, itd. Warto zwrócić uwagę, że z G+ (inne też), dostajemy już identyfikator użytkownika, który możemy powiązać ze swoim lokalnie tworzonym kontem. I gdy ponownie przyjdzie gościu z G+ i się zaloguje się i dostaniemy jego ID, będziemy wiedzieć, że on to on, a nie ktoś inny.
Na koniec jeszcze ważna sprawa, oczywiście należy pamiętać aby samodzielnie stworzyć swoje aplikacje odpowiednio na stronach:
https://developers.facebook.com/
https://apps.twitter.com/
https://console.developers.google.com/home/dashboard
Należy także ustawić poprawnie callbacki w tych systemach, u mnie wartość które działały poprawnie to: http://www.xoxox.com
Ej, ale co to za dziwny adres? No tak tak, bo Twitter nie lubi localhost (FB i G+ sobie z tym radzą). Dlatego dla Twittera robi się wyjątek i należy zaatakować windows\sytem32\drivers\etc\host dopisać taką linijkę:
127.0.0.1 www.xoxox.com
Od tej pory www.xoxox.com będzie wskazywać na wasz komputer. Ale jeszcze! Należy na normalnym IIS dodać stronę i pokazać jej, że binarki leżą u was w źródłach. Dodać binding w IIS. I na końcu w Visual Studio przełączyć się z IIS express na normalnego i też korzystać z www.xoxox.com. Można też zignorować twittera i dla testów sprawdzić tylko FB i G+ i korzystać z IIS express na 127.0.0.1
Tyle, od tej pory ja i wy (jaka jest liczna mnoga od ono?) będziemy mogli w prosty sposób logować się społecznościami. Aplikacja dostępna jest pod linkiem: https://bitbucket.org/jstadnicki/simplesociallogin
Kod do aplikacji zostały zmienione przed publikacją, także aby zadziałały należy wygenerować własne oraz podmienić. Projekt działa pod kontrolą pełnego IIS, to także należy/można zmienić.