Как получить ответ от Facebook PHP SDK после успешного входа в систему
-
21-12-2019 - |
Вопрос
Я использую CakePHP 2.4 и Facebook PHP SDK 3.2.3 для создания формы входа в систему, которая имеет два варианта:локальный логин и авторизуйтесь с помощью facebook.Я имел в виду Как мне интегрировать вход в систему Facebook SDK с cakephp 2.x? о том, как создать действия для входа в систему и просмотреть их для входа в Facebook.
Теперь у меня есть рабочий локальный логин, и когда я нажимаю на вход в Facebook, я перенаправляюсь на Facebook и обратно к моему действию входа в систему пользователей плагина.Однако я не получаю никакого ответа в $_GET['code']
или $this->request->query['code']
.
Это мое действие при входе в систему:
public function login() {
if ($this->Auth->user()) {
$this->Session->setFlash(__('You are already registered and logged in!'), 'flash_info');
$this->redirect('/');
}
if ($this->request->is('post')) {
if ($_SERVER['HTTP_HOST'] == Configure::read('webakis.touchscreen_host')) {
$this->request->data['User']['username'] = $this->request->data['User']['name'] . ' ' . $this->request->data['User']['surname'];
}
if ($this->Auth->login()) {
$this->User->id = $this->Auth->user('id');
$this->User->saveField('last_login', date('Y-m-d H:i:s'));
if ($this->here == $this->Auth->loginRedirect) {
$this->Auth->loginRedirect = '/';
}
$this->Session->setFlash(sprintf(__('%s you have successfully logged in'), $this->Auth->user('name')), 'flash_success');
if (!empty($this->request->data)) {
$data = $this->request->data[$this->modelClass];
$this->_setCookie(array('name' => 'AKIS'), 'User');
}
if (empty($data['return_to'])) {
$data['return_to'] = null;
}
$this->redirect($this->Auth->redirect($data['return_to']));
} else {
$this->Session->setFlash(__('Invalid e-mail / password combination. Please try again'), 'flash_error');
}
}
// When facebook login is used, facebook always returns $_GET['code'].
if($this->request->query('code')){ //Execution doesn't get in here
Debugger::log($this->request->query);
// User login successful
$fb_user = $this->Facebook->getUser(); # Returns facebook user_id
if ($fb_user){
Debugger::log($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('email' => $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' => 'registered'
);
// You should change this part to include data validation
$this->User->save($data, array('validate' => false));
$this->redirect('/');
// After registration we will redirect them back here so they will be logged in
//$this->redirect(Router::url('/users/login?code=true', true));
}
}
}
if (isset($this->request->params['named']['return_to'])) {
$this->set('return_to', urldecode($this->request->params['named']['return_to']));
} else {
$this->set('return_to', false);
}
$allowRegistration = Configure::read('Users.allowRegistration');
$this->set('allowRegistration', (is_null($allowRegistration) ? true : $allowRegistration));
Configure::write('keyboard', 1);
}
Не получив ответа здесь, я не могу справиться со своей логикой входа в Facebook.
Это ответы, которые я получаю, после чего facebook перенаправляет меня обратно на страницу входа в систему:
Два интересных запроса (с указанием параметров URL и местоположения):
GET oauth?....
client_id=671394586273323
ext=1406709978
hash=AeYXzQgAjCbRdY4g
redirect_uri=http://127.0.0.1.xip.io/users/users/login
ret=login
sdk=php-sdk-3.2.3
state=9d030270aa50f2e52ac4aa66a37cd0fd
Location: http://127.0.0.1.xip.io/users/users/login?code=AQC_UtjKJU8a2leJMFAB4_1qx1mh1ww0-sRWdAD5vCocfKuZPTF4iSdKYwqxQUsm9N-_1tSPGfh3LYQXbXjYeY2onVBD6gTvJ5amvRZm5ZjI1OSYoLkqgjBsdfjWSdXTigCIQLf5d180keXTCf5jRiOXi8pWi0V2UxXqVl4K9QWWq2qGfSGuXlJMr32NZqKYR0Z93LyR1EiRFJPohfo6-j0kZJrNTkljCbY16Nrq1InqQLdYwGCOSg4IrbR0auaMIWTlnUCKFCr4DT3If_5HPFEDM6ZigeUvURM-q8y-CxDrRIctSmT4Bz1UevPqR-hOMbgKGzYUplatRywzjq_-R7bt&state=9d030270aa50f2e52ac4aa66a37cd0fd#_=_
ПОЛУЧИТЬ логин?код....
code=AQC_UtjKJU8a2leJMFAB4_1qx1mh1ww0-sRWdAD5vCocfKuZPTF4iSdKYwqxQUsm9N-_1tSPGfh3LYQXbXjYeY2onVBD6gTvJ5amvRZm5ZjI1OSYoLkqgjBsdfjWSdXTigCIQLf5d180keXTCf5jRiOXi8pWi0V2UxXqVl4K9QWWq2qGfSGuXlJMr32NZqKYR0Z93LyR1EiRFJPohfo6-j0kZJrNTkljCbY16Nrq1InqQLdYwGCOSg4IrbR0auaMIWTlnUCKFCr4DT3If_5HPFEDM6ZigeUvURM-q8y-CxDrRIctSmT4Bz1UevPqR-hOMbgKGzYUplatRywzjq_-R7bt
state=9d030270aa50f2e52ac4aa66a37cd0fd
Location: http://127.0.0.1.xip.io/eng/login
Я нахожу странным, что code не является параметром URL в первом запросе, но он есть в URL, второй ответ показывает обратную ситуацию.
Хорошо, значит, это может быть проблема с маршрутизацией.
$this->set('fb_login_url', $this->Facebook->getLoginUrl(array('redirect_uri' => Router::url(array('plugin'=> 'users', 'controller' => 'users', 'action' => 'login'), true))));
Router::url() возвращает: http://127.0.0.1.xip.io/users/users/login
Мой маршрутизатор подключается:
Router::connect('/:language/login', array('plugin' => 'users', 'controller' => 'users', 'action' => 'login'), array('language' => '[a-z]{3}'));
Router::connect('/:language/logout', array('plugin' => 'users', 'controller' => 'users', 'action' => 'logout'), array('language' => '[a-z]{3}'));
Router::connect('/:language/register', array('plugin' => 'users', 'controller' => 'users', 'action' => 'add'), array('language' => '[a-z]{3}'));
Router::connect('/:language/users', array('plugin' => 'users', 'controller' => 'users'), array('language' => '[a-z]{3}'));
Router::connect('/:language/users/index/*', array('plugin' => 'users', 'controller' => 'users'), array('language' => '[a-z]{3}'));
Router::connect('/:language/users/:action/*', array('plugin' => 'users', 'controller' => 'users'), array('language' => '[a-z]{3}'));
Router::connect('/:language/users/users/:action/*', array('plugin' => 'users', 'controller' => 'users'), array('language' => '[a-z]{3}'));
Все эти URL-адреса перенаправляют на: http://127.0.0.1.xip.io/eng/login
.Это может быть проблемой, так как Facebook SDK имеет другой URL-адрес перенаправления, поэтому затем он перенаправляется на http://127.0.0.1.xip.io/users/users/login
, также есть запрос на перенаправление на http://127.0.0.1.xip.io/eng/login
.Параметр запроса "код" может быть потерян после такого перенаправления.
Решение
Как можно видеть в сетевой консоли и из заголовков, которые вы опубликовали, ваш сервер выполняет дополнительное перенаправление, и, как уже упоминалось в моем комментарии, именно здесь теряются параметры запроса.
Похоже, что URL-адрес перенаправления, который вы передаете на Facebook, неверен, это
http://127.0.0.1.xip.io/users/users/login
который, скорее всего, содержит по крайней мере избыток users
(не уверен, откуда это берется, вам придется разобраться в этом самостоятельно) если только вы не используете плагин под названием Users
который содержит контроллер с именем UsersController
, так что, возможно, это должно быть больше похоже
http://127.0.0.1.xip.io/users/login
Однако, учитывая, что ваш сервер перенаправляет на /eng/login
при доступе /users/users/login
, возможно, URL-адрес перенаправления, переданный Facebook, вообще неверен.
Итак, сначала вам нужно будет выяснить фактический правильный URL-адрес вашего логина, а затем убедиться, что Router::url()
(предполагая, что вы используете код из связанного вопроса) на самом деле генерирует именно этот URL.
Обновление
Судя по вашему обновленному вопросу, я не понимаю, почему любой из этих маршрутов должен вызывать перенаправление, это не маршруты перенаправления, а просто маршруты.Фактическое перенаправление будет происходить откуда-то еще.
В случае, если перенаправление на /eng/login
имеет прямой отступ, тогда вам нужно будет убедиться, что вы передаете этот URL-адрес в качестве URL-адреса перенаправления на Facebook, то есть правильно вызываете Router::url()
с language
установите ключ таким образом, чтобы он соответствовал вашему первому маршруту
Router::url(
array(
'plugin' => 'users',
'controller' => 'users',
'action' => 'login',
'language' => 'eng'
),
true
);
или используйте persist
опция в ваших маршрутах, чтобы звонок на Router::url()
без языкового ключа будет соответствовать вашему маршруту в случае, если текущий URL содержит языковой элемент, что-то вроде
Router::connect(
'/:language/login',
array('plugin' => 'users', 'controller' => 'users', 'action' => 'login'),
array('language' => '[a-z]{3}', 'persist' => array('language'))
);
// ...
// connect all default routes with a persistent language prefix
Router::connect(
'/:language/:controller/',
array('action' => 'index'),
array('language' => '[a-z]{3}', 'persist' => array('language'))
);
Router::connect(
'/:language/:controller/:action/*',
array(),
array('language' => '[a-z]{3}', 'persist' => array('language'))
);
или, в качестве последнего варианта, включите строку запроса в перенаправление на /eng/login
array(/* other route params */, '?' => $this->request->query)
Другие советы
Из-за проблем с маршрутизатором я изменил параметр redirect uri в $this->Facebook->getLoginUrl()
к 'redirect_uri' => Router::url('/', true).Configure::read('Config.language').'/login'
, поскольку он решает http://127.0.0.1.xip.io/eng/login
.
Теперь я понимаю $this->request->query('code')
параметр, так что мой код пока должен работать.