将Zend2应用程序与PHPBB3身份验证集成的"正确"方法是什么?

elf*_*wyn 12 php authentication phpbb3 zend-framework2 php-5.6

好的,这有点复杂,所以请耐心等待.

我现在正在运行一个PHPBB论坛,我的目标是使用其用户管理和身份验证功能创建一个Zend2 PHP应用程序,而不是构建一个全新的授权组件,而这又需要再次与论坛同步.

以下组件将在实时环境中使用: PHPBB3,Zend Framework 2(最新稳定版),Apache,PHP 5.6 +,MySQL在没有root访问权限的虚拟Linux服务器上运行.

我的开发环境(运行下面的所有示例)是: PHPBB3,Zend Framework 2(最新稳定版),XAMPP 3.2.2,启用了xdebug的PHP 5.6.21,在Windows 8上运行的MariaDB.

每当要求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();
Run Code Online (Sandbox Code Playgroud)

我已经取得了成功,包括那些没有使用框架或直接通过ajax调用php的人,但现在 - 使用Zend 2 Framework - 在包含本机PHPBB3代码时会出现多个问题.

我不得不说我不是一个经验丰富的PHP程序员,而且我现在只学习了几天Zend.

我的第一次尝试集中于在Zends中调用Zend应用程序之前集成上面的代码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();
....
Run Code Online (Sandbox Code Playgroud)

导致此错误:

可捕获的致命错误:参数1传递给Zend\Stdlib\Parameters :: __ construct()必须是类型数组,给定对象,在C:\ xampp\htdocs\myZendApp\vendor\zendframework\zend-http\src\PhpEnvironment中调用第72行的Request.php,第24行的C:\ xampp\htdocs\myZendApp\vendor\zendframework\zend-stdlib\src\Parameters.php中定义

因此,尽早调用PHPBB似乎让Zend陷入困境,我继续执行其他实现.

我最喜欢的设计包括一个单独的Authentication Zend模块,它处理PHPBB身份验证,可作为所有路由及其控制器的服务.然而,包含和调用phpbb脚本会导致可能与全局变量的大量使用相关的各种问题.

这里从一些示例代码checkActionPhpbbAuthController:

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);
}
Run Code Online (Sandbox Code Playgroud)

这里执行错误 session_begin()

致命错误:在第228行的C:\ xampp\htdocs\myZendApp\public\forums\phpbb\session.php中调用null上的成员函数header()

在调试之后,似乎所有对$ request和$ symfony_request的引用都在那些认证函数中为NULL.

在花了很多时间来识别从Zend上下文执行脚本的方法之后,我已经着眼于在单独的上下文中执行脚本的方法.我想到的最简单的方法是从一个脚本调用脚本HttpClient并使用结果文本来驱动我的身份验证服务.为此,我需要从被调用的脚本中检索会话cookie并将其存储以便在Zend应用程序中使用.

如果我通过Zend Framework引导脚本,我似乎又遇到了同样的问题(在Zend Controller中有PHBB代码),所以我不能使用Zends路由来访问它们.由于我使用的是http请求,因此我必须将脚本存储在公共目录或其子目录中.

这就是我现在所处的位置.对使用PHPBB的php文件的内部调用可以自行运行,但是HttpClient我使用(现在来自Zend Controller类)确实在每个转弯都会遇到超时,我在这里提出了另一个问题:Zend 2 Http Client从localhost/public目录请求php文件时请求超时.

我将非常感谢您的观点,提示和可能的架构,甚至是我上面提到的问题的部分解决方案.

在任何情况下我不想做的是发明我自己的身份验证和用户管理,因为它总是不如已经在PHPBB中的复杂但经过验证的系统,并且从长远来看会导致安全问题.此外,Zend应用程序被认为是"额外",因为论坛现在已成为网站的核心.

非常感谢您的时间,请索取更多信息.(我无法包含所有代码,我不知道此时还有什么与你相关)

vpa*_*era 3

PHPBB 3.x 基于 symfony 并使用 symfony 组件。您引用的帖子非常过时。

请看一下: https://github.com/phpbb/phpbb/blob/3.1.x/phpBB/config/auth.yml(PHPBB3的身份验证提供程序的容器定义)

master 上的版本 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's 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);
}
Run Code Online (Sandbox Code Playgroud)

您可以实现该接口来为您的 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();
Run Code Online (Sandbox Code Playgroud)

确保两个项目使用相同的 cookie,或者当用户登录时 zend 也设置 phpBB cookie 和会话,因为 session_start 使用它来查找会话 id:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

谢谢。