2016-06-19 43 views
12

Ok, questo è un po 'complicato, quindi abbi pazienza con me.Che cos'è il modo "a" corretto per integrare un'applicazione Zend2 con l'autenticazione PHPBB3?

Sto eseguendo un forum PHPBB da un po 'di tempo e il mio obiettivo è creare un'applicazione PHP Zend2 utilizzando le sue funzionalità di gestione utenti e autenticazione invece di creare un componente di autorizzazione completamente nuovo che a sua volta deve sincronizzarsi con il Forum di nuovo.

I seguenti componenti verranno utilizzati nell'ambiente live: PHPBB3, Zend Framework 2 (ultima versione stabile), Apache, PHP 5.6+, MySQL in esecuzione su un server Linux virtuale senza accesso root.

mio ambiente di sviluppo (l'esecuzione di tutti gli esempi di seguito) è: phpbb3, Zend Framework 2 (ultima versione stabile), XAMPP 3.2.2, PHP 5.6.21 con xdebug abilitato, MariaDB in esecuzione su Windows 8.

Ogni volta che l'integrazione di phpBB è chiesto per le seguenti linee inevitabilmente alzare nelle ricerche:

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(); 

ho già avuto successo compresi quelli senza l'utilizzo di un quadro o chiamando php direttamente tramite ajax, ma ora - utilizzando Zend Framework 2 - ci sono problemi multipli che emergono quando si include n codice PHPBB3 ativo.

Devo dire che non sono un programmatore PHP esperto e ho imparato a conoscere Zend per un paio di giorni.

Il mio primo tentativo centrata sulla integrazione del codice di cui sopra prima che l'applicazione Zend viene chiamato in 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(); 
.... 

Con conseguente questo errore:

Catchable fatal error: Argument 1 passed to Zend\Stdlib\Parameters::__construct() must be of the type array, object given, called in C:\xampp\htdocs\myZendApp\vendor\zendframework\zend-http\src\PhpEnvironment\Request.php on line 72 and defined in C:\xampp\htdocs\myZendApp\vendor\zendframework\zend-stdlib\src\Parameters.php on line 24

Quindi chiamando phpBB questo sembra presto per rovinare Zend in modo brutto sono passato ad altre implementazioni.

Il mio design preferito includerebbe un modulo di autenticazione Zend separato che gestisce l'autenticazione PHPBB ed è disponibile come servizio per tutte le rotte e i relativi controller. Includere e chiamare gli script phpbb portano tuttavia a vari problemi probabilmente legati al pesante uso di globals.

Ecco alcuni esempi di codice dal checkAction nel 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); 
} 

E qui l'errore di eseguire session_begin()

Fatal error: Call to a member function header() on null in C:\xampp\htdocs\myZendApp\public\forums\phpbb\session.php on line 228

dopo il debug in esso sembrava che tutti i riferimenti alla richiesta $ e $ symfony_request all'interno di quelle funzioni di autenticazione dove NULL.

Dopo aver sprecato molte ore nel discernere un modo per eseguire gli script dal contesto di Zend, ho messo gli occhi su un modo per eseguire gli script in un contesto separato. Il modo più semplice che mi è venuto in mente era chiamare lo script da un HttpClient e usare il testo Risultato per guidare il mio servizio di autenticazione. Per fare ciò avrei bisogno di recuperare il cookie di sessione dagli script chiamati e memorizzarlo per l'uso nell'applicazione Zend.

Se inserisco gli script in Zend Framework, mi sembra di incappare nuovamente nello stesso problema (avendo il codice PHBB in un controller Zend), quindi non posso utilizzare il routing di Zends per accedervi. Dato che sto usando una richiesta http, devo memorizzare gli script nella directory pubblica o in una sottodirectory.

Ed è qui che sono adesso. La chiamata interna ai file php che usano PHPBB funziona bene da sola, ma il HttpClient che uso (da una classe Zend Controller per ora) viene eseguito in un timeout ad ogni turno, che ho formulato in un'altra domanda qui: Zend 2 Http Client Request times out when requesting php file from localhost/public directory.

Gradirei le vostre opinioni, suggerimenti e possibili architetture o anche soluzioni parziali ai miei problemi sopra menzionati.

Quello che non voglio fare in nessuna circostanza è inventare la mia autenticazione e gestione utente in quanto sarebbe sempre inferiore al sistema complesso ma collaudato che è già in PHPBB e porta a problemi di sicurezza a lungo termine. Anche l'applicazione Zend è considerata un "Extra" poiché il Forum è il cuore del sito allo stato attuale delle cose.

Grazie mille per il vostro tempo e per favore chiedete ulteriori informazioni. (Non potrei includere tutto il codice e non so cos'altro sarebbe rilevante per te a questo punto)

+0

Se sono completamente fuori pista con quello che voglio fare vorrei anche il vostro feedback. Ho risorse molto limitate a mia disposizione, il che è il motivo più urgente per cercare di incorporare una soluzione esistente nella mia applicazione. – elfwyn

+0

Si prega di vedere la mia risposta qui sotto. Penso che lo troverai utile – vpassapera

risposta

2

PHPBB 3.x è basato su symfony e utilizza i componenti di symfony. I post che stai facendo riferimento sono estremamente obsoleti.

Si prega di dare un'occhiata a: https://github.com/phpbb/phpbb/blob/3.1.x/phpBB/config/auth.yml (definizione del contenitore di provider di autenticazione per phpbb3)

versione sul maestro https://github.com/phpbb/phpbb/blob/master/phpBB/config/default/container/services_auth.yml

E

https://github.com/phpbb/phpbb/blob/3.1.x/phpBB/phpbb/auth/provider/provider_interface.php (vedi sotto)

<?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); 
} 

L'interfaccia tu può implementare per creare un fornitore per il tuo progetto Zend framework.

Si può vedere come i provider vengono utilizzati quando si crea una sessione

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(); 

Assicurarsi che entrambi i progetti utilizzano gli stessi biscotti, o che Zend sta inoltre i cookie phpBB e sessione quando un utente sta effettuando l'accesso come session_start utilizza questo per cercare gli ID di sessione:

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; 
    } 

Grazie.

+0

Grazie per la risposta. Mi ci vorrà un po 'di tempo per sfruttare al meglio la tua analisi, ma ti ho assegnato comunque la taglia in quanto sarebbe scaduta presto altrimenti. Questo mi darà alcuni nuovi luoghi di approccio al mio problema e mi aiuterà molto. – elfwyn

+0

Grazie!Se hai altre domande o hai bisogno di me per chiarire qualcosa fammelo sapere e modificheremo la risposta come appropriato. – vpassapera

+0

La creazione di un nuovo provider di autenticazione sostituirà quello esistente per phpbb per quanto riguarda la documentazione, dal momento che solo un provider può essere attivo alla volta (che viene gestito tramite phpbb acp). Quindi, dovrei creare uno schema di autenticazione completamente nuovo per l'utilizzo sia con phpbb che con la mia applicazione, oppure c'è un modo per includere/utilizzare il provider di autenticazione di defaut esistente utilizzato in phpbb? In tal caso, dovrei ottenere un riferimento a phpbb_container per recuperare il provider. Non riesco a vedere quale sarebbe la differenza tra l'esistente e un possibile nuovo fornitore. Guarderò oltre. – elfwyn