Интеграция phpBB в сайт (Codeigniter). Сквозная авторизация

в 11:29, , рубрики: codeigniter, phpbb, сквозная авторизация

imageНесколько недель назад по некой нужде было необходимо добавить форум в только что написанный сайт. Сайт на этапе завершения, пользователей раз-два и обчелся. Сайт был написан на Codeigniter. В качестве форума был выбран phpBB, как один из распространенных free форум версии 3.1.1. После несложных манипуляций форум без проблем был установлен. Стало интереснее, когда дело дошло до пользователей.

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

Недолго погуглив, нашел вот эту статью, с которой и началось мое погружение в глубины пользовательской функциональности phpBB.

Постановка задачи

  1. Сделать безболезненную интеграцию. Должен быть один реализующий класс. Без изменений в движке форума, дабы при обновлении форума ничего не слетело.
  2. Максимальное использование функций форума в нашем классе. Городить велосипед не хочется.
  3. Реализовать совместную регистрацию, смену пароля, авторизацию, конец сеанса, блокировку и отмену блокировки пользователя на основе уже существующего функционала форума.

Анализ

После чтения доков, стало понятно, что функции управления пользователями размещаются в <корень форума>/includes/functions_user.php, а авторизация в <корень форума>/phpbb/auth/provider. В этой папке размещены функции для нескольких вариантов авторизации. Тип авторизации задается в панели администрирования форума, раздел «Общие -> Аутентификация». Я по оставил значение по умолчанию — Db.

В принципе, необходимый функционал я нашел в этих двух файла, кроме обновления данных пользователя. Далее приступаем к реализации.

Начальные данные

  1. Сайт, реализованный с помощью codeigniter.
  2. Форум phpBB.
  3. Таблица с пользователями сайта — USERS.
  4. Таблица с пользователями форума — phpbb_USERS.
  5. Регистрация/авторизация пользователей на сайте — переделанная под свои нужды библиотека Codeigniter Auth.

Решение

Задача поставлена, надо делать.

Перед началом — несколько нюансов.

  1. Необходимо отключить регистрацию пользователей на сайте. Это делается в панели администратора (Общие -> регистрация пользователей -> Разрешить смену имени пользователя -> Нет). Разрешаем пользователю регистрацию только на сайте.
  2. Запрещаем смену имени пользователя (Общие -> Регистрация пользователей -> Активация аккаунта -> Отключено).
  3. Запрещаем авторизацию с форума. Авторизацию и выход делаем только с сайта. Сделал «в лоб» — в файле <корень форума>/ucp.php сделал редиректы на соответствующие страницы на сайте. (см. строки «case 'login':», «case 'login_link':», «case 'logout':». Редирект «header('Location: /auth/login');» и «header('Location: /auth/logout');»).
  4. На сайте (если есть функция redirect()) заменить функцию redirect(), например на ciredirect(), дабы избежать конфликта имен — в phpBB есть функция с аналогичным названием.

Для codeigniter создаю библиотеку my_phplib.php (библиотека в codeigniter — это некий вспомогательный, подключаемый класс, располагающийся в папке application/libraries. В нем нет ничего необычного, так что пользователи других движков/фрейморков — не унывайте).

Итак, содержимое библиотеки:

Библиотека my_phplib.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class My_phpbblib
{
	public $phpBB_user;
	public $phpBB_auth;
	public $phpBB_db;
	public $table_prefix;

	public function __construct(){
		// определяем видимые переменные.
		global  $phpbb_root_path, 
				$phpEx, 
				$user, 
				$auth, 
				$cache, 
				$db, 
				$config, 
				$template, 
				$table_prefix,
				$request, 
				$phpbb_container,
				$symfony_request, 
				$phpbb_filesystem,
				$phpbb_log,
				$phpbb_path_helper,
				$phpbb_dispatcher;
		// Без константы никуда... 
		define('IN_PHPBB', TRUE);
		// корневая папка форума.
		$phpbb_root_path = './forum/';
		// расширение подключаемых файлов. В нашем случае - php
		$phpEx = substr(strrchr(__FILE__, '.'), 1);
		// подключаем файлы
		// конфигурационные файлы
		include($phpbb_root_path . 'common.' . $phpEx);
		include($phpbb_root_path . 'config.php.' . $phpEx);
		// Функции для работы с пользователями
		include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
		// разрешим супер глобальные массивы...
		$request->enable_super_globals();
		// запускаем сессию пользователя
		$user->session_begin();
		$auth->acl($user->data);
		$this->phpBB_user = $user;
		$this->phpBB_auth = $auth;
		$this->phpBB_db   = $db;
		$this->table_prefix   = $table_prefix;
	}

	// регистрация
	public function registration($data = array()) {
		// если данные есть, можно попробовать поработать с ними
		if(count($data) < 3){
			// нам надо как минимум 3 элемента - логин, пароль и email
			return false;
		}

		$new_phphBB_user = array();

		// логин пользователя.
		if(isset($data['username'])) return false;
		$new_phphBB_user['username'] = $data['username'];

		// пароль пользователя
		if(isset($data['user_password'])) return false;
		$new_phphBB_user['user_password'] = phpbb_hash($data['user_password']);

		// email пользователя
		if(isset($data['user_email'])) return false;
		$new_phphBB_user['user_email'] = $data['user_email'];

		// группа пользователя.
		// по умолчанию в phpBB3 следующие группы
		// - 1 - GUESTS              - гость (незарегистрированный пользователь)
		// - 2 - REGISTERED          - Зарегистрированный пользователь
		// - 3 - REGISTERED_COPPA    - Зарегистрированный пользователь COPPA
		// - 4 - GLOBAL_MODERATORS   - Супер-модераторы 
		// - 5 - ADMINISTRATORS      - Администраторы 
		// - 6 - BOTS                - Боты 
		// - 7 - NEWLY_REGISTERED    - Новые пользователи. 
		// по умолчанию регистрируем NEWLY_REGISTERED
		$new_phphBB_user['group_id'] = isset($data['group_id']) ? $data['group_id'] : 7;

		// тип пользователя.
		// есть 4 типа 
		// - 0 - Обычный пользователь
		// - 1 - Неативный пользователь. Ждет активации.
		// - 2 - Игнор пользователя (боты)
		// - 3 - Суперадмин

		// по умолчанию новый пользователь не активный. 
		$new_phphBB_user['user_type'] = isset($data['user_type']) ? $data['user_type'] : 1;

		// сохраняем пользователя в таблицах форума.
		$phphBB_user_id = user_add($user_row, false);
		
		// возвращаем id пользователя в таблицах phpBB
		return $phphBB_user_id;
	}

	// авторизация
	public function login($data = array()){
		$this->phpBB_user->setup('ucp');

		// имя пользователя
		$username    = $data['username'];

		// пароль пользователя
		$password    = $data['user_password'];

		// Запомнить пользователя
		$autologin   = $data['autologin'];

		// Показывать пользователя в онлайне
		$viewonline  = true;

		// авторизация средствами phpBB
		$result = $this->phpBB_auth->login($username, $password, $autologin, $viewonline);
		// result возвращает массив
		// array(
		// 	'status' => status-code(int),
		// 	'error_msg'=> status-message-id(text),
		// 	'user_row'=> user-row(array),
		// );
		// Статусы
		// 1  - Не указан пароль
		// 3  - успешный вход
		// 10 - Неверный логин
		// 11 - Неверный пароль
		// 12 - Пользователь неактивен
		// 13 - Превышен лимит попыток входа

		return $result;
	}

	// выход 
	public function logout(){
		$this->phpBB_user->session_kill();
		$this->phpBB_user->session_begin();
	}

	// удалить пользователя 
	public function delete_user($mode = 'remove', $user_name = '') {

		// $mode = remove/retain - удалить или оставить в базе
		// по имени пользователя получить id, так как мы считаем, что id пользователя в форуме - на сайте нам не известен.
		$sql = 'SELECT user_id, username
			FROM phpbb_users 
			WHERE username_clean = "'.utf8_clean_string($user_name).'"';

		$result = $this->phpBB_db->sql_query($sql);
		if (!($row = $this->phpBB_db->sql_fetchrow($result)))
		{
			$db->sql_freeresult($result);
		} do
		{
			$user_id_ary[] = $row['user_id'];
		}
		
		// освобождаем память.
		$this->phpBB_db->sql_freeresult($result);
		if($user_id_ary){
			// если нашли пользователя - удаляем
			return user_delete($mode, $user_id_ary, $retain_username = true);
		}
		return false;
	}

	// бан пользователю.
	public function ban_user($user_name = '', $ban_minutes = 432000, $ban_reason = ''){
		// тип бана - устанавливаем по имени пользователя
		// бывает - по имени (user), по ип (ip), по email (email)
		return user_ban('user', $user_name, $ban_minutes, $ban_len_other = '', $ban_exclude = false, $ban_reason, $ban_give_reason = '');
	}

	// разбанить пользователя.
	public function unban_user($user_name = ''){
		// тип бана - устанавливаем по имени пользователя
		// бывает - по имени (user), по ип (ip), по email (email)
		// по имени пользователя получить id банов
		$sql = 'SELECT b.ban_id, u.user_id 
				FROM phpbb_users u, phpbb_banlist b 
				WHERE u.username_clean = "'.utf8_clean_string($user_name).'" AND u.user_id = b.ban_userid';

		$result = $this->phpBB_db->sql_query($sql);
		if (!($row = $this->phpBB_db->sql_fetchrow($result)))
		{
			$this->phpBB_db->sql_freeresult($result);
		}

		do
		{
			$user_ban_id_ary[] = $row['ban_id'];
		}
		$this->phpBB_db->sql_freeresult($result);
		return user_unban('user', $user_ban_id_ary);
	}

	// обновить данные пользователя.
	public function edit_user_pass($user_name ='', $user_pass) {
		if (empty($user_name) || empty($user_pass)){
			return false;
		}

		$sql = 'UPDATE ' . $this->table_prefix . 'users 
				SET user_password="' . md5($user_pass) . '" 
				WHERE username_clean = "'.utf8_clean_string($user_name).'"';
		$this->phpBB_db->sql_query($sql);

		return true;
	}

}

Использование в codeigniter — стандартно — подключаем библиотеку в контроллере, отвечающем за авторизацию.

Использование my_phplib.php

	function __construct(){
		parent::__construct();
		$this->load->library('my_phpbblib');
	}
	
	// авторизация
	public function login(){
		/*
			Ваш код
		*/
		$data = array();
		$data['username'] = $this->input->post('login');
		$data['user_password'] = $this->input->post('pass');
		$data['autologin'] = $remember;
		// Пробуем авторизироваться и получаем ответ.
		$registration_result = $this->my_phpbblib->login($data);

		/*
			Ваш код
		*/
	}


	// регистрация
	public function registration(){
		/*
			Ваш код 
		*/


		$user_row['username'] = $user_login;
		$user_row['user_password'] = phpbb_hash($user_pass);
		$user_row['user_email'] = $user_email;
		$user_row['group_id'] = 2;
		$user_row['user_type'] = 0;
		// регистрация пользователя на форуме
		$forum_id = $this->my_phpbblib->registration($user_row);

		/*
			Ваш код 
		*/
	}

	// выход
	public function logout() {
		/*
			Ваш код 
		*/

		$this->my_phpbblib->logout($data);

		/*
			Ваш код 
		*/
	}

	// Удалить пользователя.
	public function delete($id = 0){

		/*
			Ваш код 
		*/

		$this->my_phpbblib->delete_user('remove', $user_login);

		/*
			Ваш код 
		*/
	}

	// Сменить пароль пользователю
	public function change_pass(){

		/*
			Ваш код 
		*/
		
		// изменение пароля на форуме
		$this->my_phpbblib->edit_user_pass($user_login, $user_pass);

		/*
			Ваш код 
		*/
	}


	// Заблокировать пользователя.
	public function ban(){

		/*
			Ваш код 
		*/

		// забаним пользователя и на форме.
		$b = $this->my_phpbblib->ban_user($user_login, 432000, $ban_reason);

		/*
			Ваш код 
		*/
	}

	// разблокировать пользователя.
	public function unban(){

		/*
			Ваш код 
		*/

		$ub = $this->my_phpbblib->unban_user($user_login);

		/*
			Ваш код 
		*/
	}

Данный способ был проделан с phpBB 3.1.1 и phpBB 3.1.3 (после обновления никакого вмешательства не потребовалось).

Спасибо за внимание.

Буду рад, если статья кому-нибудь поможет.

Автор: Romanche

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js