Jak zintegrować Facebook PHP SDK z Laravel 5.4?

Szukałem łatwego sposobu na integrację Facebook PHP SDK z Laravel 5.4. Zasadniczo chciałem udostępnić go jako usługę w mojej aplikacji Laravel. Oczywiście istnieje SammyK/LaravelFacebookSdk na GitHubie. Ale z jakiegoś powodu nie chciałem go używać. Czułem, że konfiguracja dodaje kolejną warstwę, którą będę musiał zrozumieć i pracować w ramach ograniczeń.

Istnieje również własny pakietSocialite . Ale to jest zasadniczo dla tylko proste uwierzytelnianie. Jeśli chcę przesłać zdjęcia, komentarze, złożyć żądania wsadowe, nie są one możliwe. Socialite nie używa PHP SDK Facebook jako zależności. Używa pakietu Guzzle do wysyłania bezpośrednich żądań API tylko do uwierzytelniania.

Ponieważ nie ma prostej odpowiedzi na bezpośrednie zintegrowanie Facebook SDK w najmniejszej liczbie kroków, pomyślałem, że napiszę to.

Author: Sriram Ranganathan, 2017-03-22

1 answers

Najpierw edycja kompozytora.json w głównym folderze projektu, aby dołączyć Facebook SDK:

{
  "require" : {
    "facebook/graph-sdk" : "~5.0"
  }
}

Następnie uruchom composer update w monicie powłoki, aby pobrać sdk do folderu dostawcy.

Teraz chcielibyśmy używać Facebook SDK w naszej aplikacji jako dostawcy usług. Ale zanim to zrobimy, ustawmy nasze app_id, app_secret i default_graph_version, które są parametrami wymaganymi podczas wysyłania zapytań do Facebook API. App_id i app_secret można uzyskać, rejestrując się na Facebook Programiści strony www.

Gdy już będziemy mieli te dane uwierzytelniające z Facebook ' a, będziemy teraz edytować plik .env w głównym folderze projektu. Dodaj je do końca:

FACEBOOK_APP_ID=xxxxxxxxxxxxxxxx
FACEBOOK_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FACEBOOK_DEFAULT_GRAPH_VERSION=v2.8

Zastąp xxx.. z wartościami podanymi Tobie. Zauważ, że nazwy zmiennych są tylko moim dziełem. Możesz je nazwać, jak chcesz. Musielibyśmy teraz użyć tych zmiennych do Ustawienia osobnego pliku konfiguracyjnego. Musimy to zrobić, abyśmy mogli użyć funkcji helper Config() Laravela do pobieraj wartości w dowolnym miejscu w aplikacji. Więc stwórzmy facebook.php w folderze config i dodaj:

<?php

return [
    'config' => [
        'app_id' => env('FACEBOOK_APP_ID', null),
        'app_secret' => env('FACEBOOK_APP_SECRET', null),
        'default_graph_version' => env('FACEBOOK_DEFAULT_GRAPH_VERSION', 'v2.8'),
    ],
];

Dzięki tej prostej konfiguracji możemy teraz wywołać config('facebook.config') z dowolnego miejsca w aplikacji. Zwróci tablicę wraz z odpowiednimi wartościami dopasowanymi z .plik env.

Facebook facebook to jeden z największych serwisów społecznościowych w Polsce, który działa na Facebooku od 1999 roku. API.

W Laravel 5.4 otwórz plik app\Providers\AppServiceProvider.php. Jeśli nie masz tego pliku lub chcesz utworzyć osobny plik, możesz utworzyć nowego dostawcę usług w powłoce:

php artisan make:provider FacebookServiceProvider

Możemy teraz edytować FacebookServiceProvider.php w folderze dostawcy. Jedyną różnicą jest to, że musimy to zarejestrować w naszym Pliku config/app.php. Na końcu tablicy $providers można dodać następujący tekst:

App\Providers\FacebookServiceProvider::class,

Aby kontynuować odpowiedni kod, w AppServiceProvider.php lub naszym nowym FacebookServiceProvider.php najpierw include: use Facebook\Facebook; na górze. Następnie w ramach register() method dodaj:

$this->app->singleton(Facebook::class, function ($app) {
            return new Facebook(config('facebook.config'));
        });

Możesz zauważyć, że wiążę klasę jako singleton, ponieważ dla mojej aplikacji chciałbym ponownie użyć tego samego obiektu z kontenera usługi. Istnieją inne typy wiązań dostarczone przez Laravel, które możesz chcieć sprawdzić.

Cały kod wyglądałby jak poniżej (używam AppServiceProvider.php):

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Facebook\Facebook;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Facebook::class, function ($app) {
            return new Facebook(config('facebook.config'));
        });
    }
}
To wszystko. Mamy teraz Facebook dostępny jako obsługa aplikacji. Możemy teraz wstrzyknąć obiekt facebook wszędzie tam, gdzie chcemy go używać w naszej aplikacji. Od tego miejsca można po prostu postępować zgodnie z instrukcjami z dokumentacji Facebook , aby wywołać ich API.'

Dodatkowe rzeczy, jako przykład:

Zanim przejdę dalej, chciałbym wspomnieć, że seria postów napisanych przez ludzi z Symfony była bardzo pomocna w zrozumieniu pojęć Service Container i Dependency Injection. Możesz je znaleźć tutaj

Spróbujmy teraz wykonać podstawową operację, taką jak odzyskanie nazwiska osoby z facebook ' a. Facebook Facebook Facebook API pozwala na uzyskanie informacji o użytkowniku Facebooka poprzez wysłanie podstawowych parametrów: facebook id użytkownika wraz z tokenem dostępowym.w celu uzyskania informacji o użytkowniku facebook API należy skorzystać z API Facebook API, wysyłając podstawowe parametry: identyfikator użytkownika facebook id wraz z tokenem dostępowym. Nazwijmy je odpowiednio uid i access_token. Trzeba by je odzyskać za pomocą jednej z metod Facebook ' a:

  1. FacebookRedirectLoginHelper-gdy chcesz, aby uwierzytelnianie facebook stało się z po stronie serwera.
  2. [[91]}FacebookCanvasHelper-do uwierzytelniania aplikacji po stronie klienta [92]}
  3. FacebookJavaScriptHelper-dla uwierzytelniania javascript po stronie klienta
Możesz skonfigurować odpowiedni rodzaj uwierzytelniania, wykonując kroki opisane w Przewodniku Facebook ' a pierwsze kroki .

Moja aplikacja jest dość prosta, więc poszedłem z uwierzytelniania javascript po stronie klienta. Ja również używam jquery obok. Ponieważ używam silnika łopatkowego Laravela, mój javascript został osadzony bezpośrednio w pliku widoku, dzięki czemu mogłem włączyć csrf_token() Laravela i korzystać z innych funkcji pomocniczych, takich jak url(). Javascript po stronie klienta wygląda jak poniżej. Pamiętaj, aby zastąpić appId wartościami i zapisać plik jako login.blade.php.

<html>
<head>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<button id="btn-login" type="button" class="btn btn-primary btn-lg">
    <span> Login with Facebook</span>
</button>

<script>
$(document).ready(function() {
    $.ajaxSetup({ cache: true }); // since I am using jquery as well in my app
    $.getScript('//connect.facebook.net/en_US/sdk.js', function () {
        // initialize facebook sdk
        FB.init({
            appId: 'xxxxxxxxxxxxxxxx', // replace this with your id
            status: true,
            cookie: true,
            version: 'v2.8'
        });

        // attach login click event handler
        $("#btn-login").click(function(){
            FB.login(processLoginClick, {scope:'public_profile,email,user_friends', return_scopes: true});  
        });
    });

// function to send uid and access_token back to server
// actual permissions granted by user are also included just as an addition
function processLoginClick (response) {    
    var uid = response.authResponse.userID;
    var access_token = response.authResponse.accessToken;
    var permissions = response.authResponse.grantedScopes;
    var data = { uid:uid, 
                 access_token:access_token, 
                 _token:'{{ csrf_token() }}', // this is important for Laravel to receive the data
                 permissions:permissions 
               };        
    postData("{{ url('/login') }}", data, "post");
}

// function to post any data to server
function postData(url, data, method) 
{
    method = method || "post";
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", url);
    for(var key in data) {
        if(data.hasOwnProperty(key)) 
        {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", data[key]);
            form.appendChild(hiddenField);
         }
    }
    document.body.appendChild(form);
    form.submit();
}

</script>
</body>
</html>

Jeśli aplikacja ma inny zestaw uprawnień niż użytkownik, edytuj pole scope. Wszystkie dostępne uprawnienia facebook zobacz tutaj .

Więc w zasadzie mój kod ma przycisk logowania i kiedy użytkownik kliknie go, javascript sdk kopnie i wyskakuje okno logowania. Gdy użytkownik się zaloguje, zamieszczam dane z powrotem na serwer, tak jakby był zamieszczany formularz.

Teraz z powrotem na stronę serwera, ponieważ mamy uid i access_token możemy przechowywać je w bazie danych, a następnie wykonać proste wywołanie do Facebook API z naszego serwera. Aby otrzymać dane formularza, należy ustawić trasę w routes/web.php:

Route::post('login', 'FacebookUser@store');

Make FacebookUser controller at shell:

php artisan make:controller FacebookUser

A kod kontrolera jest jak następuje:

<?php

namespace App\Http\Controllers;

use Request;
use App\User; // you need to define the model appropriately
use Facebook\Facebook;

class FacebookUser extends Controller
{
    public function store(Facebook $fb) //method injection
    {
        // retrieve form input parameters
        $uid = Request::input('uid');
        $access_token = Request::input('access_token');
        $permissions = Request::input('permissions');

        // assuming we have a User model already set up for our database
        // and assuming facebook_id field to exist in users table in database
        $user = User::firstOrCreate(['facebook_id' => $uid]); 

        // get long term access token for future use
        $oAuth2Client = $fb->getOAuth2Client();

        // assuming access_token field to exist in users table in database
        $user->access_token = $oAuth2Client->getLongLivedAccessToken($access_token)->getValue();
        $user->save();

        // set default access token for all future requests to Facebook API            
        $fb->setDefaultAccessToken($user->access_token);

        // call api to retrieve person's public_profile details
        $fields = "id,cover,name,first_name,last_name,age_range,link,gender,locale,picture,timezone,updated_time,verified";
        $fb_user = $fb->get('/me?fields='.$fields)->getGraphUser();
        dump($fb_user);
    }    
}

Zauważ, że za pomocą setDefaultAccessToken() obiekt $fb może być pobrany z kontenera usługi w dowolnej części późniejszego przetwarzania bazy kodu aplikacji. $fb można użyć bezpośrednio do wysłania żądania interfejsu API Facebook. Nie ma potrzeby ponownego budowania $fb przy użyciu app_id, app_secret i nie ma potrzeby ponownego ustawiania tokenu dostępu dla bieżącego użytkownika podczas bieżącego cyklu życia żądania-odpowiedzi. Dzieje się tak dlatego, że $fb jest singletonem, a więc ten sam obiekt jest zwracany, gdy kontener usługi jest wywoływany dla Facebook serwis podczas bieżącego cyklu życia żądania-odpowiedzi.

Jeśli nie możesz wykonać metody iniekcji, aby uzyskać obiekt $fb, to istnieją inne sposoby jego rozwiązania. Moim ulubionym jest używanie helpera resolve(), ponieważ działa niezależnie od kontekstu obiektu lub statycznej funkcji w klasie.

$fb = resolve('Facebook\Facebook');
 50
Author: Sriram Ranganathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-10 01:00:00