All Projects → kalynrobinson → flarum-laravel-integration

kalynrobinson / flarum-laravel-integration

Licence: other
Example and guide to integrating Flarum with Laravel's basic auth.

Programming Languages

PHP
23972 projects - #3 most used programming language
HTML
75241 projects
Vue
7211 projects

Projects that are alternatives of or similar to flarum-laravel-integration

oauth
Allow users to log in with GitHub, Twitter, Facebook, and more!
Stars: ✭ 21 (-19.23%)
Mutual labels:  flarum
passport
The Laravel passport compatible oauth extension for your Flarum forum.
Stars: ✭ 24 (-7.69%)
Mutual labels:  flarum
fluxbb to flarum
🚀 FluxBB to Flarum importer
Stars: ✭ 14 (-46.15%)
Mutual labels:  flarum
Flarum
Flarum - 优雅自由的 PHP 轻社区
Stars: ✭ 1,588 (+6007.69%)
Mutual labels:  flarum
mondedie-chat
Node.js chat application using Express, Socket.io, Redis and Mithril
Stars: ✭ 40 (+53.85%)
Mutual labels:  flarum
extension-generator
This package is no longer supported. Please use https://github.com/flarum/cli instead.
Stars: ✭ 53 (+103.85%)
Mutual labels:  flarum
flarum-ext-sso
🔒 Single Sign On for Flarum.
Stars: ✭ 59 (+126.92%)
Mutual labels:  flarum
masquerade
User profile builder extension for your Flarum forum.
Stars: ✭ 17 (-34.62%)
Mutual labels:  flarum
flarum-discussion-views
An extension for the Flarum forum software which tracks and displays discussion views.
Stars: ✭ 26 (+0%)
Mutual labels:  flarum
analytics
A Flarum extension that provides your forum piwik's and google's analytics features
Stars: ✭ 32 (+23.08%)
Mutual labels:  flarum
Flarum
Simple forum software for building great communities.
Stars: ✭ 12,190 (+46784.62%)
Mutual labels:  flarum
awesome-flarum
A curated list of amazingly awesome Flarum extensions and resources.
Stars: ✭ 151 (+480.77%)
Mutual labels:  flarum
flarum-mobile-ios
An iOS Webview wrapper for Flarum
Stars: ✭ 32 (+23.08%)
Mutual labels:  flarum
Core
Simple forum software for building great communities.
Stars: ✭ 5,372 (+20561.54%)
Mutual labels:  flarum
links
Manage Flarum primary navigation links
Stars: ✭ 31 (+19.23%)
Mutual labels:  flarum
flarum-ext-dashboard
DEPRECATED This completely re-imagines the Admin interface
Stars: ✭ 17 (-34.62%)
Mutual labels:  flarum
api-docs
Flarum API Docs
Stars: ✭ 15 (-42.31%)
Mutual labels:  flarum
french
French language pack to localize the Flarum forum software plus its official and third-party extensions.
Stars: ✭ 17 (-34.62%)
Mutual labels:  flarum
user-bio
Add a User Bio feature to Flarum
Stars: ✭ 16 (-38.46%)
Mutual labels:  flarum
bazaar
The extension marketplace for your Flarum forum.
Stars: ✭ 58 (+123.08%)
Mutual labels:  flarum

Flarum-Laravel Integration

Example and guide to integrating Flarum with Laravel's basic auth.

Credits

Tutorial

Prerequisites

  • An Apache/PHP/MySQL stack. See WAMP, LAMP, and XAMPP for all-in-one stack managers.
  • Composer

Database Setup

  • Create databases for your Laravel and Flarum sites
  • If you have already have databases setup, skip this step
    mysqli -u <username> -p
      > create database demo;
      > create database demo_laravel;
      > quit

Flarum Setup

  • Install Flarum as normal
    cd path/to/your/project
    mkdir flarum
    cd flarum
    composer create-project flarum/flarum . --stability=beta
    composer install
  • If installation fails, make sure you meet Flarum's system requirements and that the necessary extensions are enabled in your php.ini
  • Start up your Apache web server and configure Flarum to your liking
  • Disable user sign-up in the admin panel

Laravel Setup

  • Create a new Laravel project and generate basic user authentication views
cd path/to/your/project
laravel new demo
cd demo
php artisan make:auth
  • Edit the .env file with your MySQL credentials and the name of your Laravel database (e.g. demo)
  • Run your migrations and start up the server to make sure everything works as expected, e.g. registration, login, and logout
php artisan migrate
php artisan serve

API Key

  • Generate a 40 character string to use as an API key
  • Add the API key and the credentials to your .env
FLARUM_API_KEY=jy8HbVSSh0BjGFTnM4mlN9WVPEu31YbZEFkBAu9E

OPTIONAL Seeding the API Key

  • If you skip this step, manually insert the above API key into your Flarum api_keys table
  • I've chosen to insert the API key into my Flarum api_keys table when seeding my Laravel app
  • This is not mandatory (and I doubt this is a best practice, but it was convenient for my use case)
  • Add your Flarum database credentials to .env
FLARUM_DATABASE=demo_flarum
FLARUM_USERNAME=root
FLARUM_PASSWORD=secret
  • Add a Flarum database connection to config/database.php, using the .env properties added above
    'default' => env('DB_CONNECTION', 'mysql'),
    
    'connections' => [

        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],
        
        // Flarum database, used only for setup
        'flarum' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('FLARUM_DATABASE', 'forge'),
            'username' => env('FLARUM_USERNAME', 'forge'),
            'password' => env('FLARUM_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

    ],
  • Make sure your default connection is set to your MySQL database
  • Modify seeds/DatabaseSeeder.php to insert your API key
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Create initial API key
        DB::connection('flarum')->table('api_keys')->insert([
            'id' => config('flarum.api_key')
        ]);
    }
}

OPTIONAL Setup the Queue

  • While a queue is not strictly necessary, it's good practice for when you need to chain jobs together—in my case, I want to activate a Flarum user immediately after registration, but the registration request must resolve first
  • If you skip this step, remove implements ShouldQueue from the following event subscriber
  • Generate a queue table, migrate the changes, and start up the queue worker
php artisan queue:table
php artisan migrate
php artisan queue:work
  • Leave the queue worker running in the background

Setup Event Subscriber

  • Laravel's basic authentication fires off a handful of convenient events that we can listen for, namely Login, Logout, and Registered
  • If you are using a different authentication setup, you may have to implement these events yourself and/or replace the event references in the following code samples
  • Create an event subscriber and stub out the initial listeners
<?php

namespace App\Listeners;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class FlarumEventSubscriber implements ShouldQueue
{
    private $api_url;
    private $api_key;
    private $root;
    private $password_token;
    private const REMEMBER_ME_KEY = 'flarum_remember';
    private const SESSION_KEY = 'flarum_session';
    private const LIFETIME_IN_SECONDS = 99999999;
  
    public $queue = 'flarum';

    public function __construct()
    {
        $this->api_url = config('flarum.url');
        $this->api_key = config('flarum.api_key');
        $this->root = config('flarum.root');
    }
  
    public function onUserRegistration($event)
    {
    }
    
    public function onUserLogin($event)
    {
    }
    
    public function onUserLogout($event)
    {
    }
  
    public function subscribe($events)
    {
        $events->listen(
            'Illuminate\Auth\Events\Registered',
            'App\Listeners\FlarumEventSubscriber@onUserRegistration'
        );

        $events->listen(
            'Illuminate\Auth\Events\Login',
            'App\Listeners\FlarumEventSubscriber@onUserLogin'
        );
        
        $events->listen(
            'Illuminate\Auth\Events\Logout',
            'App\Listeners\FlarumEventSubscriber@onUserLogout'
        );
    }
  • Note FlarumEventSubscriber#subscribe—this registers your event listeners
  • Register this subscriber with the event provider /providers/EventServiceProvider
protected $subscribe = [
    'App\Listeners\FlarumEventSubscriber',
];

On User Registration

  • When a user registers, we want to use its credentials to create a matching user in our Flarum database
  • We can do this by POSTing a request to Flarum's JSON API, which, while mostly undocumented, is straightforward enough
public function onUserRegistration($event)
{
    $user = $event->user;
    $method = 'POST';
    $endpoint = '/api/users';

    $data = [
      'data' => [
          'attributes' => [
              'id'       => $user->id,
              'username' => $user->name,
              'password' => $user->password,
              'email'    => $user->email
          ]
      ]
  ];

  $this->sendRequest($endpoint, $method, $data);
}

private function sendRequest($endpoint, $method, $data)
{
    $data_string = json_encode($data);
    $ch = curl_init($this->api_url . $endpoint);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt(
      $ch,
      CURLOPT_HTTPHEADER,
      [
          'Content-Type: application/json',
          'Content-Length: ' . strlen($data_string),
          'Authorization: Token ' . $this->api_key . '; userId=1',
      ]
    );
    $result = curl_exec($ch);
    return json_decode($result, true);
}
  • This request should only be sent over HTTPS; it includes the user's hashed password

On User Login

  • When a user logs in, we want to GET a Flarum session token and store it as a cookie
public function onUserLogin($event)
{
    $user = $event->user;
    $response = $this->authenticate($user->name, $user->password);
    $token = $response['token'] ?: '';
    $this->setRememberMeCookie($token);
}

private function authenticate($id, $password)
{
    $endpoint = '/api/token';
    $method = 'POST';

    $data = [
        'identification' => $id,
        'password' => $password,
        'lifetime' => self::LIFETIME_IN_SECONDS
    ];
    
    return $this->sendRequest($endpoint, $method, $data);
}

private function setRememberMeCookie($token)
{
    $this->setCookie(self::REMEMBER_ME_KEY, $token, time() + self::LIFETIME_IN_SECONDS);
}

private function removeRememberMeCookie()
{
    $this->setCookie(self::REMEMBER_ME_KEY, '', time() - 10);
}

private function setCookie($key, $token, $time, $path = '/')
{
    setcookie($key, $token, $time, $path, $this->root);
}

On User Logout

  • When a user logs out, we want to remove the cookie added during login, as well as the Flarum session cookie
public function onUserLogout($event)
{
    $this->removeRememberMeCookie();
    $this->setCookie('flarum_session', '', time() - 10);
    $this->setCookie('flarum_session', '', time() - 10, '/flarum');
}

Done!

  • Basic registration, login, and logout should be synced across your Laraval and Flarum sites
  • If you want to automatically activate the Flarum users, you can queue an activation request immediately after registration or you can create your own event and event listener
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].