28 grudnia 2018

Logowanie przy pomocy konta Facebook w CakePhp 3.x

Tworząc mój super tajny projekt (a będzie on niebawem opisany również na tym blogu) musiałem wykonać opcję logowania przy pomocy konta Facebook. Uznałem że warto podzielić się gotowcem i przy okazji go troszkę opisać.

Tworząc aplikację, działamy na serwerze produkcyjnym oraz developerskim, czasem do poprawnego działania aplikacji na różnych serwerach potrzebne jest zdefiniowanie różnych wartości dla tych samych zmiennych. Warto więc stworzyć sobie nowy plik env.php (ja go umieściłem wewnątrz katalogu „config”) oraz dodać do wyjątków w git. Aby nie został automatycznie przesłany na serwer developerski z wartościami skierowanymi tylko dla developmentu

.gitignore

/config/env.php

Do pliku „config/app.php” należy dopisać na samej górze, aby plik ten został załadowany do projektu jeszcze przed konfiguracją aplikacji.

config/app.php

include('env.php');

config/env.php

//FACEBOOK
define("FB_LOGIN_URL", "xxx");
define("FB_APP_ID","xxx");
define("FB_APP_SECRET","xxx");

Powyżej dałem również zawartość pliku „env.php” jak widzicie definiujemy tam trzy stałe, będą one wykorzystane później w kodzie.
Dzięki takiemu zabiegowi, możemy na serwerze produkcyjnym podać inne wartości, aby logowanie przebiegało bez problemowo w obu środowiskach.
Metodę taką wykorzystuję również do np. wyłączenia captchy na serwerze developerskim.

Do prawidłowego działania, niezbędna jest baza danych, w niej tabelka „users

users table

CREATE TABLE `users` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Uuid` char(40) COLLATE utf8_polish_ci DEFAULT NULL,
  `First_name` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  `Last_name` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  `Email` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  `Created` datetime DEFAULT NULL,
  `Id_facebook` bigint(99) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `id_UNIQUE` (`Id`),
  UNIQUE KEY `uuid_UNIQUE` (`Uuid`),
  UNIQUE KEY `id_facebook_UNIQUE` (`Id_facebook`)
) ENGINE=InnoDB AUTO_INCREMENT=55 DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci

Uruchomienie

Do uruchomienia potrzebujemy oczywiście CakePhp 3.x

composer.phar create-project --prefer-dist cakephp/app my_app_name

Oraz Facebook SDK

composer require facebook/graph-sdk

Objaśnienie

W pliku config/facebook.php stworzona jest konfiguracja, do niej wpadają nasze stałe środowiskowe (te wpisane w pliku env.php) oraz tablica z danymi które od użytkownika facebook’a chcemy pobrać (nazwa „fbPermissions”).

Najważniejszą rzeczą jest natomiast komponent facebook, musimy go załadować w AppController aby jego klasa była widoczna w każdej części naszego programu.

Sprawdzenie czy użytkownik został zalogowany, robimy w poniższy sposób, jeśli metoda isLogin() zwróci false, oznacza że nie jesteśmy zalogowani.

if($this->User->isLogin()==false)

Przykład znajduje się w pliku „PagesController.php:30”.

Gdybyśmy chcieli przekazać do widoku link do logowania się poprzez konto facebook, musimy w kontrolerze wpisać:

$this->set('LoginUrlFb', $this->Facebook->getLoginUrl());

Przy każdym kontolerze, musimy wywołać funkcję init facebook’a. Właśnie w tym miejscu pobieramy z konfiguracji Facebook dane takie jak appSecret, appId i przekazujemy do init jako parametry.

$this->Facebook->init(Configure::read('Facebook.appId'), Configure::read('Facebook.appSecret'));

W UsersController posiadamy dwie metody, pierwsza z nich to fb() służy ona do logowania użytkownika za pomocą konta facebook, jeśli użytkownik nie istnieje (linia: 38) użytkownik zostanie zapisany do naszej bazy danych oraz zalogowany (stworzymy sesję). Jeśli użytkownik już u nas w bazie się znajduje, pominiemy krok zapisania rekordu, będziemy tylko logować

Metoda getUserFb() pobiera wszystkie dane zwrócone przez api facebooka, takie jak email, firstname itd. Jeśli chcemy otrzymać więcej danych, musimy wrócić do konfiguracji Facebook jaką stworzyliśmy i dopisać w tablicy „fbPermissions” rzeczy które wymaga nasza aplikacja do poprawnego działania.

Zachęcam do eksperymentowania ponieważ powyższy skrypt powstał na moje potrzeby i każdy powinien dokonać modyfikacji na swoje własne potrzeby.

Github

https://github.com/rafaldanis/fb_login.git