Integracja CakePHP 2.x Auth z Facebooka Auth do uwierzytelnienia użytkownika szwu
Na początek należy zapoznać się na fantastycznej CakePHP Auth Component i postępuj Simple Authentication and Authorization Application tutorial z 2.x książki CakePHP (zakładając, że również po dwa pierwsze tutoriale z serii. Po zakończeniu, należy udało się zbudować prostą aplikację CakePHP z uwierzytelniania i autoryzacji użytkowników.
następnie należy pobrać facebook SDK i uzyskać App ID z facebook.
Najpierw skopiujmy plik Facebook do aplikacji/sprzedawców. Następnie zaimportujemy i zainicjujemy go w metodzie AppController beforeFilter.
//app/Controller/AppController.php
public function beforeFilter() {
App::import('Vendor', 'facebook-php-sdk-master/src/facebook');
$this->Facebook = new Facebook(array(
'appId' => 'App_ID_of_facebook',
'secret' => 'App_Secret'
));
$this->Auth->allow('index', 'view');
}
Inicjujemy pakiet SDK Facebooka w AppController, dzięki czemu będziemy mieć do niego dostęp za pośrednictwem aplikacji. Następnie wygenerujemy adres URL logowania na Facebooku przy użyciu zestawu SDK i przekażemy go do widoku. Zwykle robię to w metodzie beforeRender.
Uwaga: Powyższe dane konfiguracyjne (appId & secret) najlepiej zapisywać w App/Config/facebook.php. Powinieneś wtedy użyć cake Configure.
//app/Controller/AppController.php
public function beforeRender() {
$this->set('fb_login_url', $this->Facebook->getLoginUrl(array('redirect_uri' => Router::url(array('controller' => 'users', 'action' => 'login'), true))));
$this->set('user', $this->Auth->user());
}
Będziemy aktualizować nasz układ tak, że możemy wyświetlić ten link do facebook logowania dla wszystkich użytkowników, którzy nie zalogowany. Zauważ, jak ustaliliśmy redirect_uri
naszego działania aplikacji użytkownika/login. Jest tak, że gdy facebook uwierzytelnił użytkownika, możemy zalogować go również za pomocą Cake :: Auth. Istnieją różne korzyści z tego, including the solution for this question.
<!-- App/Views/Layouts/default.ctp just after <div id="content"> -->
<?php
if($user) echo 'Welcome ' . $user['username'];
else {
echo $this->Html->link('Facebook Login', $fb_login_url) . ' | ';
echo $this->Html->link('Logout', array('controller' => 'user', 'action' => 'logout'));
?>
Gdy użytkownik kliknie link logowania, facebook SDK będzie zalogować użytkownika i przekierować je do naszej aplikacji Users/login. Zaktualizujemy tę akcję, aby obsłużyć to:
// App/Controller/UsersController.php
// Handles login attempts from both facebook SDK and local
public function login()
{
// If it is a post request we can assume this is a local login request
if ($this->request->isPost()){
if ($this->Auth->login()){
$this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash(__('Invalid Username or password. Try again.'));
}
}
// When facebook login is used, facebook always returns $_GET['code'].
elseif($this->request->query('code')){
// User login successful
$fb_user = $this->Facebook->getUser(); # Returns facebook user_id
if ($fb_user){
$fb_user = $this->Facebook->api('/me'); # Returns user information
// We will varify if a local user exists first
$local_user = $this->User->find('first', array(
'conditions' => array('username' => $fb_user['email'])
));
// If exists, we will log them in
if ($local_user){
$this->Auth->login($local_user['User']); # Manual Login
$this->redirect($this->Auth->redirectUrl());
}
// Otherwise we ll add a new user (Registration)
else {
$data['User'] = array(
'username' => $fb_user['email'], # Normally Unique
'password' => AuthComponent::password(uniqid(md5(mt_rand()))), # Set random password
'role' => 'author'
);
// You should change this part to include data validation
$this->User->save($data, array('validate' => false));
// After registration we will redirect them back here so they will be logged in
$this->redirect(Router::url('/users/login?code=true', true));
}
}
else{
// User login failed..
}
}
}
I skończymy! Większość ciężkiego podnoszenia odbywa się za pomocą tej akcji, jak widać. Najlepiej przenieść część powyższego kodu do UserModel. Oto podsumowanie tego, co się dzieje.
Najpierw sprawdzamy, czy żądanie logowania jest wysyłane z formularza logowania naszej aplikacji @ Użytkownicy/login. Jeśli tak, to po prostu logujemy użytkownika.W przeciwnym razie sprawdzamy, czy użytkownik istnieje w naszej bazie danych i czy loguje się do niego lub tworzy nowego użytkownika, a następnie loguje go.
Należy zweryfikować użytkownika tutaj, wysyłając więcej niż e-mail, np. Jego facebook_id . W przeciwnym razie istnieje ryzyko, że użytkownik może zmienić e-mail na Facebooku i przejąć innego użytkownika aplikacji.
Happy Coding!
Witam Shafee, podążyłem za wami przykładem, jednak z jakiegoś powodu otrzymuję tę wiadomość 1 na 10 razy. "OAuthException: aktywny token dostępu musi być użyty do zapytania informacji o bieżącym użytkowniku" Czy masz jakieś rozwiązania? – Chris
Wydaje się być prawidłowym podejściem (jeszcze nie testowane). Czy mógłbyś oznaczyć to jako akceptowaną odpowiedź, ponieważ tego właśnie używasz? – Nunser
Dziękuję człowieku, bardzo mi to pomogło, jedyne, co chciałbym osiągnąć to mieć wyskakujące okna logowania, zamiast przekierowania do nowego adresu URL: dodanie '" display "=>" popup ",' do getLoginUrl nie działa. Dzięki – dav