Let’s get started by creating a new Laravel project by running

composer create project laravel/laravel acme

Add laravel/socialite and facebook/graph-sdk to composer.json file

"require": { [...] // other dependencies "facebook/graph-sdk": "^5.6", "laravel/socialite": "^3.0", }, 1 2 3 4 5 "require" : { [ . . . ] // other dependencies "facebook/graph-sdk" : "^5.6" , "laravel/socialite" : "^3.0" , } ,

and run composer install to install them. We are using socialite package to authenticate users with Facebook OAuth service. After authentication, we’ll be storing user access token in the database and use it to make calls to OAuth service on the user’s behalf. I wrote a very detailed tutorial on social authentication with socialite. Follow the steps below to integrate Facebook SDK in your laravel application and using it to post to profile and pages.

Step 1: Create a Facebook App.

Visit facebook developers console and create a new app. Fill in details and create App ID. We’ll be using this app to authenticate users and post on their behalf. Go to Settings > Basic and copy app id and secret. Add a new product and choose Facebook login.

Step 2: Populate Facebook Credentials

Edit config/service.php file. Add following lines at the end of the services array.

'facebook' => [ 'client_id' => env('FACEBOOK_CLIENT_ID'), // Your Facebook App Client ID 'client_secret' => env('FACEBOOK_CLIENT_SECRET'), // Your Facebook App Client Secret 'redirect' => env('FACEBOOK_REDIRECT'), // Your application route used to redirect users back to your app after authentication 'default_graph_version' => 'v2.12', ], 1 2 3 4 5 6 'facebook' = > [ 'client_id' = > env ( 'FACEBOOK_CLIENT_ID' ) , // Your Facebook App Client ID 'client_secret' = > env ( 'FACEBOOK_CLIENT_SECRET' ) , // Your Facebook App Client Secret 'redirect' = > env ( 'FACEBOOK_REDIRECT' ) , // Your application route used to redirect users back to your app after authentication 'default_graph_version' = > 'v2.12' , ] ,

Edit your project’s .env file.

FACEBOOK_CLIENT_ID=APP_CLIENT_ID FACEBOOK_CLIENT_SECRET=APP_SECRET FACEBOOK_REDIRECT=https://localhost:3000/login/facebook/callback 1 2 3 FACEBOOK_CLIENT_ID = APP_CLIENT_ID FACEBOOK_CLIENT_SECRET = APP_SECRET FACEBOOK_REDIRECT = https : //localhost:3000/login/facebook/callback

Step 3: Add Redirect URL to App Valid OAuth Redirect URIs

Go to your App > Products > Facebook Login > Settings and update Valid OAuth Redirect URIs. For apps created after March 2018, it’s compulsory to use HTTPS to use OAuth service. Even if you’re requesting from your local dev environment, you must have https enabled to make use of their service. You can’t disable Enforce HTTPS options in your app settings. If you’re on Windows platform, you can easily configure XAMPP to use HTTPS. If you’re running Linux, you can use a self-signed certificate with nginix or apache. After settings up your self-signed certs, you can enable allow-insecure-localhost flag in chrome://flags settings to allow requests to localhost over HTTPS even when an invalid certificate is presented.

Step4: Integrating Facebook

We are using Laravel service providers to bootstrap Facebook to avoid unnecessary instantiation of Facebook object every time we’ll be making calls to Facebook OAuth service. Create a new FacebookServiceProvider.

php artisan make:provider FacebookServiceProvider

Now edit app/Providers/FacebookServiceProviders.php and add following code.

<?php namespace App\Providers; use Facebook\Facebook; use Illuminate\Support\ServiceProvider; class FacebookServiceProvider extends ServiceProvider { /** * Bootstrap the application services. * * @return void */ public function boot() { // } /** * Register the application services. * * @return void */ public function register() { $this->app->singleton(Facebook::class, function ($app) { $config = config('services.facebook'); return new Facebook([ 'app_id' => $config['client_id'], 'app_secret' => $config['client_secret'], 'default_graph_version' => 'v2.6', ]); }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php namespace App \ Providers ; use Facebook \ Facebook ; use Illuminate \ Support \ ServiceProvider ; class FacebookServiceProvider extends ServiceProvider { /** * Bootstrap the application services. * * @return void */ public function boot ( ) { // } /** * Register the application services. * * @return void */ public function register ( ) { $this -> app -> singleton ( Facebook:: class , function ( $app ) { $config = config ( 'services.facebook' ) ; return new Facebook ( [ 'app_id' = > $config [ 'client_id' ] , 'app_secret' = > $config [ 'client_secret' ] , 'default_graph_version' = > 'v2.6' , ] ) ; } ) ; } }

In register() method of our service provider, we are defining an implementation of Facebook\Facebook in the service container. We are using Laravel’s built-in config() method to retrieve Facebook OAuth credentials from config/services.php file and using it to construct Facebook class object which we will be using throughout our application to make calls to Facebook API.

Step 4: Database Migrations

After populating database credentials in your project’s .env file. Modify and run migrations to create database tables nessary to store our OAuth user. This is what our User migration looks like.

public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password')->nullable(); // Set to nullable $table->string('token'); // OAuth Token $table->rememberToken(); $table->timestamps(); }); } 1 2 3 4 5 6 7 8 9 10 11 12 public function up ( ) { Schema:: create ( 'users' , function ( Blueprint $table ) { $table -> increments ( 'id' ) ; $table -> string ( 'name' ) ; $table -> string ( 'email' ) -> unique ( ) ; $table -> string ( 'password' ) -> nullable ( ) ; // Set to nullable $table -> string ( 'token' ) ; // OAuth Token $table -> rememberToken ( ) ; $table -> timestamps ( ) ; } ) ; }

Step 5: Setting up authentication routes and controllers

Run php artisan make:auth to generate Laravel’s default authentication scaffolding. Edit routes/web.php file to add social authentication routes.

Route::get('/login/facebook', 'Auth\LoginController@redirectToFacebookProvider'); Route::get('login/facebook/callback', 'Auth\LoginController@handleProviderFacebookCallback'); 1 2 3 Route:: get ( '/login/facebook' , 'Auth\LoginController@redirectToFacebookProvider' ) ; Route:: get ( 'login/facebook/callback' , 'Auth\LoginController@handleProviderFacebookCallback' ) ;

Edit app/Http/Controllers/Auth/LoginController.php

<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\User; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Support\Facades\Auth; use Laravel\Socialite\Facades\Socialite; class LoginController extends Controller { use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = '/home'; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest')->except('logout'); } /** * Redirect the user to the Facebook authentication page. * * @return \Illuminate\Http\Response */ public function redirectToFacebookProvider() { return Socialite::driver('facebook')->scopes([ "publish_actions, manage_pages", "publish_pages"])->redirect(); } /** * Obtain the user information from Facebook. * * @return void */ public function handleProviderFacebookCallback() { $auth_user = Socialite::driver('facebook')->user(); $user = User::updateOrCreate( [ 'email' => $auth_user->email ], [ 'token' => $auth_user->token, 'name' => $auth_user->name ] ); Auth::login($user, true); return redirect()->to('/'); // Redirect to a secure page } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 <?php namespace App \ Http \ Controllers \ Auth ; use App \ Http \ Controllers \ Controller ; use App \ User ; use Illuminate \ Foundation \ Auth \ AuthenticatesUsers ; use Illuminate \ Support \ Facades \ Auth ; use Laravel \ Socialite \ Facades \ Socialite ; class LoginController extends Controller { use AuthenticatesUsers ; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = '/home' ; /** * Create a new controller instance. * * @return void */ public function __construct ( ) { $this -> middleware ( 'guest' ) -> except ( 'logout' ) ; } /** * Redirect the user to the Facebook authentication page. * * @return \Illuminate\Http\Response */ public function redirectToFacebookProvider ( ) { return Socialite:: driver ( 'facebook' ) -> scopes ( [ "publish_actions, manage_pages" , "publish_pages" ] ) -> redirect ( ) ; } /** * Obtain the user information from Facebook. * * @return void */ public function handleProviderFacebookCallback ( ) { $auth_user = Socialite:: driver ( 'facebook' ) -> user ( ) ; $user = User:: updateOrCreate ( [ 'email' = > $auth_user -> email ] , [ 'token' = > $auth_user -> token , 'name' = > $auth_user -> name ] ) ; Auth:: login ( $user , true ) ; return redirect ( ) -> to ( '/' ) ; // Redirect to a secure page } }

In redirectToFacebookProvider() method, we are requesting publish and manage permissions for profile and pages by using Socialite scopes method. App user will be redirected to Facebook OAuth page after visiting /login/facebook route. Upon accepting they will be redirected back to login/facebook/callback route and we will retrieve their access token and profile details to create a new user or update existing one with a fresh token. Now we’ll be using this token to make calls to Graph API on the behalkf of user.

Retrieving User Profile via the Graph API

Let’s create a new controller to handle requests for using Graph API.

php artisan make:controller GraphController

Add an authenticated route to routes/web.php

Route::group(['middleware' => [ 'auth' ]], function(){ Route::get('/user', 'GraphController@retrieveUserProfile'); }); 1 2 3 4 5 Route:: group ( [ 'middleware' = > [ 'auth' ] ] , function ( ) { Route:: get ( '/user' , 'GraphController@retrieveUserProfile' ) ; } ) ;

Now define retrieveUserProfile method in GraphController

<?php namespace App\Http\Controllers; use Facebook\Exceptions\FacebookSDKException; use Facebook\Facebook; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class GraphController extends Controller { private $api; public function __construct(Facebook $fb) { $this->middleware(function ($request, $next) use ($fb) { $fb->setDefaultAccessToken(Auth::user()->token); $this->api = $fb; return $next($request); }); } public function retrieveUserProfile(){ try { $params = "first_name,last_name,age_range,gender"; $user = $this->api->get('/me?fields='.$params)->getGraphUser(); dd($user); } catch (FacebookSDKException $e) { } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php namespace App \ Http \ Controllers ; use Facebook \ Exceptions \ FacebookSDKException ; use Facebook \ Facebook ; use Illuminate \ Http \ Request ; use Illuminate \ Support \ Facades \ Auth ; class GraphController extends Controller { private $api ; public function __construct ( Facebook $fb ) { $this -> middleware ( function ( $request , $next ) use ( $fb ) { $fb -> setDefaultAccessToken ( Auth:: user ( ) -> token ) ; $this -> api = $fb ; return $next ( $request ) ; } ) ; } public function retrieveUserProfile ( ) { try { $params = "first_name,last_name,age_range,gender" ; $user = $this -> api -> get ( '/me?fields=' . $params ) -> getGraphUser ( ) ; dd ( $user ) ; } catch ( FacebookSDKException $e ) { } } }

Posting to Profiles

Add a new method publishToProfile to GraphController for handling requests to create profile posts.

public function publishToProfile(Request $request){ try { $response = $this->api->post('/me/feed', [ 'message' => $request->message ])->getGraphNode()->asArray(); if($response['id']){ // post created } } catch (FacebookSDKException $e) { dd($e); // handle exception } } 1 2 3 4 5 6 7 8 9 10 11 12 public function publishToProfile ( Request $request ) { try { $response = $this -> api -> post ( '/me/feed' , [ 'message' = > $request -> message ] ) -> getGraphNode ( ) -> asArray ( ) ; if ( $response [ 'id' ] ) { // post created } } catch ( FacebookSDKException $e ) { dd ( $e ) ; // handle exception } }

Add a corresponding route to routes/web.php call it.

<?php [...] Route::group(['middleware' => [ 'auth' ]], function(){ Route::get('/user', 'GraphController@retrieveUserProfile'); Route::post('/user', 'GraphController@publishToProfile'); }); 1 2 3 4 5 6 7 8 9 10 11 12 <?php [ . . . ] Route:: group ( [ 'middleware' = > [ 'auth' ] ] , function ( ) { Route:: get ( '/user' , 'GraphController@retrieveUserProfile' ) ; Route:: post ( '/user' , 'GraphController@publishToProfile' ) ; } ) ;

To confirm if your post was created, you can check id on the response object. If the request was successful it will be populated with the id of the newly created node. In case of an unsuccessful request, it will be null.

Posting to Pages

Method of posting to pages is different from profiles. When you’re posting to your profile, you’re using your own access token to make the request. Every page your manage has its own access token and you have to retrieve it before making any requests. Add a new method getPageAccessToken to GraphController

public function getPageAccessToken($page_id){ try { // Get the \Facebook\GraphNodes\GraphUser object for the current user. // If you provided a 'default_access_token', the '{access-token}' is optional. $response = $this->api->get('/me/accounts', Auth::user()->token); } catch(FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); exit; } catch(FacebookSDKException $e) { // When validation fails or other local issues echo 'Facebook SDK returned an error: ' . $e->getMessage(); exit; } try { $pages = $response->getGraphEdge()->asArray(); foreach ($pages as $key) { if ($key['id'] == $page_id) { return $key['access_token']; } } } catch (FacebookSDKException $e) { dd($e); // handle exception } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public function getPageAccessToken ( $page_id ) { try { // Get the \Facebook\GraphNodes\GraphUser object for the current user. // If you provided a 'default_access_token', the '{access-token}' is optional. $response = $this -> api -> get ( '/me/accounts' , Auth:: user ( ) -> token ) ; } catch ( FacebookResponseException $e ) { // When Graph returns an error echo 'Graph returned an error: ' . $e -> getMessage ( ) ; exit ; } catch ( FacebookSDKException $e ) { // When validation fails or other local issues echo 'Facebook SDK returned an error: ' . $e -> getMessage ( ) ; exit ; } try { $pages = $response -> getGraphEdge ( ) -> asArray ( ) ; foreach ( $pages as $key ) { if ( $key [ 'id' ] == $page_id ) { return $key [ 'access_token' ] ; } } } catch ( FacebookSDKException $e ) { dd ( $e ) ; // handle exception } }

We’re passing $page_id to getPageAccessToken to retrieve access token. You can get your page id from about section of your facebook page. After retrieving all pages, we are returning access token. Now we’ll use this token to post to a page. Add publishToPage method to GraphController and route to call it.

public function publishToPage(Request $request){ $page_id = 'YOUR_PAGE_ID'; try { $post = $this->api->post('/' . $page_id . '/feed', array('message' => request->message), $this->getPageAccessToken($page_id)); $post = $post->getGraphNode()->asArray(); dd($post); } catch (FacebookSDKException $e) { dd($e); // handle exception } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public function publishToPage ( Request $request ) { $page_id = 'YOUR_PAGE_ID' ; try { $post = $this -> api -> post ( '/' . $page_id . '/feed' , array ( 'message' = > request -> message ) , $this -> getPageAccessToken ( $page_id ) ) ; $post = $post -> getGraphNode ( ) -> asArray ( ) ; dd ( $post ) ; } catch ( FacebookSDKException $e ) { dd ( $e ) ; // handle exception } }

Route::group(['middleware' => [ 'auth' ]], function(){ Route::get('/user', 'GraphController@retrieveUserProfile'); Route::post('/user', 'GraphController@publishToProfile'); Route::post('/page', 'GraphController@publishToPage'); }); 1 2 3 4 5 6 7 8 9 Route:: group ( [ 'middleware' = > [ 'auth' ] ] , function ( ) { Route:: get ( '/user' , 'GraphController@retrieveUserProfile' ) ; Route:: post ( '/user' , 'GraphController@publishToProfile' ) ; Route:: post ( '/page' , 'GraphController@publishToPage' ) ; } ) ;

Creating Photo Posts

public function publishToProfile(Request $request){ $absolute_image_path = '/var/www/larave/storage/app/images/lorde.png'; try { $response = $this->api->post('/me/feed', [ 'message' => $request->message, 'source' => $this->api->fileToUpload('/path/to/file.jpg') ])->getGraphNode()->asArray(); if($response['id']){ // post created } } catch (FacebookSDKException $e) { dd($e); // handle exception } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public function publishToProfile ( Request $request ) { $absolute_image_path = '/var/www/larave/storage/app/images/lorde.png' ; try { $response = $this -> api -> post ( '/me/feed' , [ 'message' = > $request -> message , 'source' = > $this -> api -> fileToUpload ( '/path/to/file.jpg' ) ] ) -> getGraphNode ( ) -> asArray ( ) ; if ( $response [ 'id' ] ) { // post created } } catch ( FacebookSDKException $e ) { dd ( $e ) ; // handle exception } }

To create a media post, all you have to do is to pass source along with text message. It should be an instance of FacebookFile entity. Calling fileToUpload('/path/to/file.jpg') with absolute image path also return an instance of FacebookFile.

I hope after following above steps, you’ll be able to easily integrate Facebook SDK into your Laravel app. I’ve also created an example project repository on github. However, If you’re still facing any issue, please comment and I’ll try to help you solve your problem.