Как получить ответ от Facebook PHP SDK после успешного входа в систему

Я использую 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

Мне кажется странным, что код не является параметром 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. Параметр запроса «код» может быть потерян после этого перенаправления.


person kaktusas2598    schedule 30.07.2014    source источник
comment
Рекомендуется не создавать повторяющиеся вопросы, а просто редактировать исходный вопрос. В случае, если он не получил достаточного внимания, вы всегда можете получить репутацию и предложить награду... в любом случае, до сих пор не ясно, действительно ли вы убедились, что Facebook не перенаправляет с параметром запроса code! Вы проверили, например, сетевую консоль вашего браузера, чтобы увидеть, что именно происходит, возможно, параметр теряется в дополнительном перенаправлении на вашем сервере?   -  person ndm    schedule 30.07.2014
comment
Извините за дубликат, мне действительно нужно, чтобы он работал на работе. Я зарегистрировал $this->request->query['code'] в своем коде, но он ничего не напечатал. И как мне проверить в консоли firebug, если параметр потерян?   -  person kaktusas2598    schedule 30.07.2014
comment
Вы почти у цели, так как видите перенаправления Facebook с параметром code, а с вашего сервера возвращается статус 302, т.е. другое перенаправление, поэтому переключайтесь на вкладку Заголовки и ищите ответ Location заголовок, он будет содержать URL-адрес перенаправления, который, как я полагаю, не содержит параметров запроса.   -  person ndm    schedule 30.07.2014
comment
Я обновил статью с информацией о двух конкретных ответах   -  person kaktusas2598    schedule 30.07.2014


Ответы (2)


Как видно из сетевой консоли и из заголовков, которые вы разместили, ваш сервер выполняет дополнительную переадресацию, и, как уже упоминалось в моем комментарии, именно здесь теряются параметры запроса.

Похоже, что 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)
person ndm    schedule 30.07.2014
comment
$this->set('fb_login_url', $this->Facebook->getLoginUrl(array('redirect_uri' => Router::url(array('controller' => 'users', 'action' => 'login'), true)))); Я использую роутер таким образом, попробую добавить к нему 'plugin' => 'users' - person kaktusas2598; 30.07.2014
comment
URL-адрес, который я получаю от Router::url: 'http://127.0.0.1.xip.io/users/users/login'. Я думаю, что это может быть неправильно, но у меня он подключен к моему маршрутизатору как Router::connect('/:language/users/users/:action/*', array('plugin' => 'users', 'controller' => 'users'), array('language' => '[a-z]{3}')); - person kaktusas2598; 30.07.2014
comment
Я могу ввести разные URL-адреса для доступа к странице входа, например http://127.0.0.1.xip.io/eng/users/login или http://127.0.0.1.xip.io/eng/users/users/login. Из-за того, что мой маршрутизатор подключается, но он всегда перенаправляет на http://127.0.0.1.xip.io/eng/login - person kaktusas2598; 30.07.2014
comment
@ kaktusas2598 Значит, перенаправление на /eng/login не предназначено? Оттуда практически невозможно дать вам какой-либо совет, не видя всей картины, такой как подключенные маршруты, конфигурация вашего компонента аутентификации, фактическое местоположение вашего пользовательского контроллера и т. д. Все, что я вижу отсюда, это то, что маршрут, который вы показываете может отсутствовать параметр persist для языкового элемента. - person ndm; 30.07.2014
comment
Users Controller находится в папке app/plugin/Users/Controller. Я добавил информацию о маршрутах. Я надеюсь, что это может помочь немного. - person kaktusas2598; 30.07.2014
comment
@ kaktusas2598 Я не понимаю, почему любой из этих маршрутов должен вызывать перенаправление, это не маршруты перенаправления, а просто маршруты. Фактическое перенаправление будет происходить откуда-то еще. Я обновил свой ответ. - person ndm; 30.07.2014
comment
Спасибо за ваши ответы, это сработало, хотя в какой-то момент я получил около 302 запросов на вход, а затем перенаправил с facebook. Проверьте мой ответ, возможно, это не лучшее решение, но оно работает. - person kaktusas2598; 30.07.2014

Из-за проблем с маршрутизатором я изменил параметр 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'), так что пока мой код должен работать.

person kaktusas2598    schedule 30.07.2014