Disclaimer: I do not claim that my remarks point to right direction with respect to the integration between external site and phpbb. In many cases there may be much better solutions, like external authentication system (used by both sites). There are also some obvious problems, like security issues with sending user data, forum's permissions system etc. For this reason I think that making a 'plug and play' extension out of this is very unlikely. I just wanted simple working solution, and that's it. I didn't found much info how to do that, hence I share my ideas.
As for the code, the typical Guzzle request to forum's API point looks like:
Code: Select all
$client = new GuzzleHttp\Client(['cookies' => true]);
Then you need to grab users forum's session cookies
COOKIENAME_u, COOKIENAME_sid (in order to have access to them, forum and the main site should share domain). If you read cookies to $forumCookies, then you create CookieJar for Guzzle:
Code: Select all
$cookieJar=GuzzleHttp\Cookie::fromArray($forumCookies, COOKIE_DOMAIN);
With that data, a simple request for forums API looks like:
Code: Select all
try {
$response = $client->post(API_POINT_URL,
['cookies' => $cookieJar,
'headers' => ['User-Agent' => USER_AGENT],
GuzzleHttp\RequestOptions::JSON => ['ip' => USER_IP,
'sec' => SOME_SEC_TOKEN,
'username' => USERNAME,
'password' => PASSWORD,...etc.]
]);
} catch (GuzzleHttp\Exception\GuzzleException $ex) {
SOME_FAILURE_LOGIC
}
On the forum side, I need to subscribe to
core.session_ip_after event and execute this kind of logic:
Code: Select all
public function changeIp(data $event)
{
if (!CHECK THAT YOU ARE IN API REQUEST) { //otherwise it gets executed on all sites
return;
}
if (!$jsonPost = file_get_contents('php://input')) { //read json body request
return;
};
$jsonData = json_decode($jsonPost, true);
if ($jsonData === null) {
return;
}
$ip = (string) $jsonData['ip'];
$ipSec = (string) $jsonData['sec']; //SOME security token
if (SECURITY OK) {
if (filter_var($ip, FILTER_VALIDATE_IP)) {
$event['ip'] = $retIp;
SOME (ABSTRACT) CONTROLLER ::$data=$jsonData; //save data in static field for use in controller
}
}
}
And controllers are very thin, for example login controller:
Code: Select all
public function handle(): JsonResponse
{
if (self::$data === null || !isset(self::$data['username']) ||
!isset(self::$data['password'])) {
return ERROR_RESPONSE;
}
$result = $this->auth->login($data['username'], self::$data['password'], false, false, 0);
$status = $result['status'];
if (SOME LOGIC DEPENDING ON STATUS)
....
return SOME JSON RESPONSE.
}
Finally, one needs to send new forum's cookies (saved by Guzzle in $cookieJar) to the user - details depends on the backend used in the main site.
Then one needs to secure communication between Main site and forum, and restrict it to POST request - this is easily done in extension's routing.yaml.
Very sketchy, but this should give you the main idea.