Подтвердить что ты не робот

Что такое "правильный" способ интеграции приложения Zend2 с аутентификацией PHPBB3?

Хорошо, это немного сложно, так что несите меня.

Я запускаю PHPBB Forum в течение некоторого времени, и моя цель - создать PHP-приложение Zend2 с использованием его функций управления пользователями и аутентификации вместо создания совершенно нового компонента авторизации, который, в свою очередь, должен синхронизироваться с форумом еще раз.

Следующие компоненты будут использоваться в живой среде: PHPBB3, Zend Framework 2 (последняя стабильная версия), Apache, PHP 5.6+, MySQL, работающая на виртуальном сервере Linux без доступа root.

Моя среда разработки (все приведенные ниже примеры): PHPBB3, Zend Framework 2 (последняя стабильная версия), XAMPP 3.2.2, PHP 5.6.21 с включенным xdebug, MariaDB, работающим в Windows 8.

Всякий раз, когда требуется интегрировать PHPBB, следующие строки неизбежно появляются в результатах поиска:

global $phpbb_root_path, $phpEx, $user, $db, $config, $cache, $template;
define('IN_PHPBB', true);
$phpbb_root_path = './forum/phpBB3/'; // this path is from an external example
$phpEx = substr(strrchr(__FILE__, '.'), 1);
$phpBBFile = $phpbb_root_path . 'common.' . $phpEx;
include($phpBBFile);

// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup();

У меня уже был успех, в том числе без использования фреймворка или путем прямого вызова php через ajax, но теперь - с использованием Zend 2 Framework - при включении собственного кода PHPBB3 возникает множество проблем.

Я должен сказать, что я не опытный PHP-программист, и я узнал о Zend всего пару дней.

Моя первая попытка была сосредоточена на интеграции вышеуказанного кода до того, как приложение Zend вызывается в Zends index.php:

....
// Setup autoloading
require 'init_autoloader.php';

global $phpbb_root_path, $phpEx, $user, $db, $config, $cache, $template;
define('IN_PHPBB', true);
$phpbb_root_path = 'public/forums/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
$phpBBFile = $phpbb_root_path . 'common.' . $phpEx;
include($phpBBFile);

// Run the application!
Zend\Mvc\Application::init(require 'config/application.config.php')->run();
....

Результат этой ошибки:

Допустимая фатальная ошибка: аргумент 1 передан в Zend\Stdlib\Parameters:: __ construct() должен быть из массива типов,     объект, вызываемый в C:\xampp\htdocs\myZendApp\vendor\zendframework\zend-http\src\PhpEnvironment\Request.php     в строке 72 и определен в C:\xampp\htdocs\myZendApp\vendor\zendframework\zend-stdlib\src\Parameters.php в строке 24

Таким образом, вызов PHPBB на ранней стадии, похоже, испортил Zend в плохом ключе, я перешел к другим реализациям.

Мой предпочтительный дизайн будет включать отдельный модуль аутентификации Zend, который обрабатывает аутентификацию PHPBB и доступен как услуга для всех маршрутов и их контроллеров. Включение и вызов сценариев phpbb, однако, приводит к различным проблемам, вероятно, связанным с интенсивным использованием глобальных переменных.

Вот пример кода из checkAction в PhpbbAuthController:

public function checkAction(){
    global $phpbb_root_path, $phpEx, $user, $db, $config, $cache, $template;
    define('IN_PHPBB', true);
    $phpbb_root_path = 'public/forums/';
    $phpEx = substr(strrchr(__FILE__, '.'), 1);
    $phpBBFile = $phpbb_root_path . 'common.' . $phpEx;
    include($phpBBFile);

    $user->session_begin();
    $auth->acl($user->data);
    $user->setup();

    $response = array();
    if ($user->data['user_id'] == ANONYMOUS) {
        $response['loginState'] = "logged_out";
    } else {
        $response['loginState'] = "logged_in";
    }
    return new ViewModel($response);
}

И здесь ошибка при выполнении session_begin()

Неустранимая ошибка: вызовите заголовок функции-члена() в нуле     C:\xampp\htdocs\myZendApp\public\forums\phpbb\session.php в строке 228

После отладки в нее казалось, что все ссылки на $request и $symfony_request внутри этих функций аутентификации, где NULL.

После того, как мы потратили много времени на то, чтобы выполнить сценарии из контекста Zend, я поставил глаза на способ выполнения сценариев в отдельном контексте. Самый простой способ, который пришел мне на ум, состоял в том, чтобы вызвать script из HttpClient и использовать текст Result для управления моей службой аутентификации. Для этого мне нужно будет извлечь куки файл сеанса из вызываемых скриптов и сохранить его для использования в приложении Zend.

Если я направляю скрипты через Zend Framework, я, похоже, снова сталкиваюсь с той же проблемой (с кодом PHBB в контроллере Zend), поэтому я не могу использовать маршрутизацию Zends для доступа к ним. Поскольку я использую http-запрос, я должен хранить сценарии в общедоступном каталоге или в его подкаталоге.

И вот где я сейчас. Внутренний вызов файлов php, использующих PHPBB, отлично работает сам по себе, но HttpClient, который я использую (из класса Zend Controller на данный момент), запускает тайм-аут на каждом шагу, который я сформулировал в другом вопросе здесь: Задержка запроса клиента Zend 2 Http при запросе php файла из локального/общедоступного каталога.

Я был бы признателен за ваши взгляды, подсказки и возможные архитектуры или даже частичное решение моих проблем, упомянутых выше.

То, что я не хочу делать ни при каких обстоятельствах, - это изобретать мою собственную аутентификацию и администрирование пользователей, поскольку она всегда будет уступать сложной, но проверенной системе, которая уже находится в PHPBB, и в конечном итоге приводит к проблемам безопасности. Кроме того, приложение Zend считается "Extra", так как Форум является ядром сайта, так как сейчас ситуация стоит.

Большое спасибо за ваше время и, пожалуйста, запросите дополнительную информацию. (Я не мог включить весь код, и я не знаю, что еще будет иметь для вас отношение в данный момент)

4b9b3361

Ответ 1

PHPBB 3.x основан на symfony и использует компоненты symfony. Сообщения, на которые вы ссылаетесь, крайне устарели.

Пожалуйста, взгляните на: https://github.com/phpbb/phpbb/blob/3.1.x/phpBB/config/auth.yml (определение контейнера поставщиков аутентификации для PHPBB3)

Версия для мастера https://github.com/phpbb/phpbb/blob/master/phpBB/config/default/container/services_auth.yml

и

https://github.com/phpbb/phpbb/blob/3.1.x/phpBB/phpbb/auth/provider/provider_interface.php (показано ниже)

<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\auth\provider;
/**
* The interface authentication provider classes have to implement.
*/
interface provider_interface
{
    /**
     * Checks whether the user is currently identified to the authentication
     * provider.
     * Called in acp_board while setting authentication plugins.
     * Changing to an authentication provider will not be permitted in acp_board
     * if there is an error.
     *
     * @return  boolean|string  False if the user is identified, otherwise an
     *                          error message, or null if not implemented.
     */
    public function init();
    /**
     * Performs login.
     *
     * @param   string  $username   The name of the user being authenticated.
     * @param   string  $password   The password of the user.
     * @return  array   An associative array of the format:
     *                      array(
     *                          'status' => status constant
     *                          'error_msg' => string
     *                          'user_row' => array
     *                      )
     *                  A fourth key of the array may be present:
     *                  'redirect_data' This key is only used when 'status' is
     *                  equal to LOGIN_SUCCESS_LINK_PROFILE and its value is an
     *                  associative array that is turned into GET variables on
     *                  the redirect url.
     */
    public function login($username, $password);
    /**
     * Autologin function
     *
     * @return  array|null  containing the user row, empty if no auto login
     *                      should take place, or null if not impletmented.
     */
    public function autologin();
    /**
     * This function is used to output any required fields in the authentication
     * admin panel. It also defines any required configuration table fields.
     *
     * @return  array|null  Returns null if not implemented or an array of the
     *                      configuration fields of the provider.
     */
    public function acp();
    /**
     * This function updates the template with variables related to the acp
     * options with whatever configuraton values are passed to it as an array.
     * It then returns the name of the acp file related to this authentication
     * provider.
     * @param   array   $new_config Contains the new configuration values that
     *                              have been set in acp_board.
     * @return  array|null      Returns null if not implemented or an array with
     *                          the template file name and an array of the vars
     *                          that the template needs that must conform to the
     *                          following example:
     *                          array(
     *                              'TEMPLATE_FILE' => string,
     *                              'TEMPLATE_VARS' => array(...),
     *                          )
     *                          An optional third element may be added to this
     *                          array: 'BLOCK_VAR_NAME'. If this is present,
     *                          then its value should be a string that is used
     *                          to designate the name of the loop used in the
     *                          ACP template file. When this is present, an
     *                          additional key named 'BLOCK_VARS' is required.
     *                          This must be an array containing at least one
     *                          array of variables that will be assigned during
     *                          the loop in the template. An example of this is
     *                          presented below:
     *                          array(
     *                              'BLOCK_VAR_NAME'    => string,
     *                              'BLOCK_VARS'        => array(
     *                                  'KEY IS UNIMPORTANT' => array(...),
     *                              ),
     *                              'TEMPLATE_FILE' => string,
     *                              'TEMPLATE_VARS' => array(...),
     *                          )
     */
    public function get_acp_template($new_config);
    /**
    * Returns an array of data necessary to build custom elements on the login
    * form.
    *
    * @return   array|null  If this function is not implemented on an auth
    *                       provider then it returns null. If it is implemented
    *                       it will return an array of up to four elements of
    *                       which only 'TEMPLATE_FILE'. If 'BLOCK_VAR_NAME' is
    *                       present then 'BLOCK_VARS' must also be present in
    *                       the array. The fourth element 'VARS' is also
    *                       optional. The array, with all four elements present
    *                       looks like the following:
    *                       array(
    *                           'TEMPLATE_FILE'     => string,
    *                           'BLOCK_VAR_NAME'    => string,
    *                           'BLOCK_VARS'        => array(...),
    *                           'VARS'              => array(...),
    *                       )
    */
    public function get_login_data();
    /**
     * Performs additional actions during logout.
     *
     * @param   array   $data           An array corresponding to
     *                                  \phpbb\session::data
     * @param   boolean $new_session    True for a new session, false for no new
     *                                  session.
     */
    public function logout($data, $new_session);
    /**
     * The session validation function checks whether the user is still logged
     * into phpBB.
     *
     * @param   array   $user
     * @return  boolean true if the given user is authenticated, false if the
     *                  session should be closed, or null if not implemented.
     */
    public function validate_session($user);
    /**
    * Checks to see if $login_link_data contains all information except for the
    * user_id of an account needed to successfully link an external account to
    * a forum account.
    *
    * @param    array   $login_link_data    Any data needed to link a phpBB account to
    *                               an external account.
    * @return   string|null Returns a string with a language constant if there
    *                       is data missing or null if there is no error.
    */
    public function login_link_has_necessary_data($login_link_data);
    /**
    * Links an external account to a phpBB account.
    *
    * @param    array   $link_data  Any data needed to link a phpBB account to
    *                               an external account.
    */
    public function link_account(array $link_data);
    /**
    * Returns an array of data necessary to build the ucp_auth_link page
    *
    * @param int $user_id User ID for whom the data should be retrieved.
    *                       defaults to 0, which is not a valid ID. The method
    *                       should fall back to the current user ID in this
    *                       case.
    * @return   array|null  If this function is not implemented on an auth
    *                       provider then it returns null. If it is implemented
    *                       it will return an array of up to four elements of
    *                       which only 'TEMPLATE_FILE'. If 'BLOCK_VAR_NAME' is
    *                       present then 'BLOCK_VARS' must also be present in
    *                       the array. The fourth element 'VARS' is also
    *                       optional. The array, with all four elements present
    *                       looks like the following:
    *                       array(
    *                           'TEMPLATE_FILE'     => string,
    *                           'BLOCK_VAR_NAME'    => string,
    *                           'BLOCK_VARS'        => array(...),
    *                           'VARS'              => array(...),
    *                       )
    */
    public function get_auth_link_data($user_id = 0);
    /**
    * Unlinks an external account from a phpBB account.
    *
    * @param    array   $link_data  Any data needed to unlink a phpBB account
    *                               from a phpbb account.
    */
    public function unlink_account(array $link_data);
}

Интерфейс, который вы можете реализовать для создания поставщика для вашего проекта фреймворка Zend.

Вы можете видеть, как поставщики используются при создании сеанса.

https://github.com/phpbb/phpbb/blob/master/phpBB/phpbb/session.php#L560

    /* @var $provider_collection \phpbb\auth\provider_collection */
    $provider_collection = $phpbb_container->get('auth.provider_collection');
    $provider = $provider_collection->get_provider();
    $this->data = $provider->autologin();

Убедитесь, что оба проекта используют одни и те же файлы cookie или что zend также устанавливает cookie и сеанс phpBB, когда пользователь входит в систему, поскольку session_start использует это для поиска идентификаторов сеанса:

    if ($request->is_set($config['cookie_name'] . '_sid', \phpbb\request\request_interface::COOKIE) || $request->is_set($config['cookie_name'] . '_u', \phpbb\request\request_interface::COOKIE))
    {
        $this->cookie_data['u'] = request_var($config['cookie_name'] . '_u', 0, false, true);
        $this->cookie_data['k'] = request_var($config['cookie_name'] . '_k', '', false, true);
        $this->session_id       = request_var($config['cookie_name'] . '_sid', '', false, true);

        $SID = (defined('NEED_SID')) ? '?sid=' . $this->session_id : '?sid=';
        $_SID = (defined('NEED_SID')) ? $this->session_id : '';

        if (empty($this->session_id))
        {
            $this->session_id = $_SID = request_var('sid', '');
            $SID = '?sid=' . $this->session_id;
            $this->cookie_data = array('u' => 0, 'k' => '');
        }
    }
    else
    {
        $this->session_id = $_SID = request_var('sid', '');
        $SID = '?sid=' . $this->session_id;
    }

Спасибо.