PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, January 6, 2022

[FIXED] Facebook login in laravel 5.2 can't hold the session after redirect

 January 06, 2022     facebook-graph-api, facebook-php-sdk, laravel-5.2, php     No comments   

Issue

I am using Facebook PHP SDK to log my user.

I created a guard called login for this

Here is my config file of auth.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
    ],
    'admin'=>[
        'driver'=>'session',
        'provider'=>'adminusers',
    ],
    'verify'=>[
        'driver'=>'session',
        'provider'=>'verify',
    ],
    'login'=>[
        'driver'=>'session',
        'provider'=>'users'
    ]
],

to access Facebook api i created a class in App\services namespace called it Facebook

App\Services\Facbook.php

<?php
namespace App\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;

use App\Extensions\Facebook\FacebookLaravelPersistentDataHandler; 
use Facebook\Facebook as FB;
use App;

class Facebook{

protected $fb;

protected $helper;

protected $permission;

protected $log;

protected $canvashelper;

protected $persistentDataHandler;

function __construct()
{
    $this->fb   =   new FB([
                    'app_id'=>Config::get('facebook.app_id'),
                    'app_secret'=>Config::get('facebook.app_secret'),
                    'default_graph_version' => Config::get('facebook.default_graph_version'),
                    'persistent_data_handler' => new FacebookLaravelPersistentDataHandler(),
                    ]);

    $this->helper = $this->fb->getRedirectLoginHelper();

    $this->permission = Config::get('facebook.permission');

    $this->log = new Logging(Config::get('facebook.logfile'),'Facebook Log');

    $this->canvashelper =   $this->fb->getCanvasHelper();

    $this->persistentDataHandler = new FacebookLaravelPersistentDataHandler();
}

public function FBAuthUrl()
{
    if($this->isFBAuth())
    {
        return $this->helper->getLogoutUrl($this->persistentDataHandler->get('facebook_access_token'),route('facebook.logout'));
    }
    else
    {
        return $this->helper->getLoginUrl(route('facebook.callback'),$this->permission);
    }
}

public function LoginCallback()
{           
    $accessToken = $this->helper->getAccessToken(); 
    if(isset($accessToken))
    {   
        $this->persistentDataHandler->set('facebook_access_token',(string) $accessToken);
    }

}

public function isFBAuth()
{
    return $this->persistentDataHandler->has('facebook_access_token');
}

public function getFBUser()
{
    if($this->isFBAuth())
    {
        $this->fb->setDefaultAccessToken($this->persistentDataHandler->get('facebook_access_token'));
        /*,user_birthday,user_tagged_places*/
        $response = $this->fb->get("/me?fields=id,name,first_name,last_name,age_range,link,gender,locale,picture,timezone,updated_time,verified,email");
        return $response->getGraphUser();
    }
    else
    {
        return false;
    }
}

public function logout()
{
    $this->persistentDataHandler->delete('facebook_access_token');
    $this->persistentDataHandler->delete('state');
}

}

And Here is my UserController Where i write my login logic

    class UserController extends Controller
{
    .....
/*
 * Facebook login callback function
 * @param Object App\services\Facebook
 * return redirect
 */

public function fbLogin(Facebook $facebook)
{
    $facebook->LoginCallback();

    /*
     * get the usergraphnode from facebook
     */
    $fbUser = $facebook->getFBUser();

    /*
     * Convert UserGraphNode User To Eloquent User
     */
    $user = $this->getFBLoggedUser($fbUser);        

    /*
     * Here Log the user in laravel System
     */
    Auth::guard('login')->login($user);
    //dump(Auth::guard($this->guard)->user());
    dump(session()->all());
    return reidrect('/');
}


public function getFBLoggedUser($fbUser)
{
    if(User::where('email','=',$fbUser->getField('email'))->count())
    {
        $user = User::where('email','=',$fbUser->getField('email'))->first();
        if($user->fb_app_id){
            $user->fb_app_id = $fbUser->getField('id');
            $user->save();
        }
    }
    else
    {
        $user = $this->FBregister($fbUser);
    }
    return $user;
}


/**
 * Register The user logged in from Facebook
 *
 * @param \Facebook\GraphNodes\GraphUser;
 * 
 * return  \App\Models\User
 */
public function FBregister($fbUser)
{
    $user = new User();
    $user->fname = $fbUser->getField('first_name');
    $user->lname = $fbUser->getField('last_name');
    $user->gender = $fbUser->getField('gender');
    $user->email = $fbUser->getField('email');
    $user->fb_app_id = $fbUser->getField('id');

    $picture = $fbUser->getField('picture');
    if($picture->isSilhouette()){
        $user->profile_image = $picture->getUrl();
    }

    $user->save();

    return $user;
}

.........
}

On Successful Facebook login redirect i am calling UserController@fbLogin after calling Auth::guard()->login() i dump session it successfully show a login_login_randomstring=>UserId i session . but When i redirect it all session data lost.

But the weird thing is that it only happen when it calling through facebook redirect. If i use this function like normal login routes it works perfactaly like this

in route.php

Route::get('/login','UserController@login');

and in UserController

function login(){
 $user = User::find(12);
 Auth::guard('login')->login($user);
 return redirect('/');
}

Using this method i can easily access Session data after redirecting from here but in facebook case it doesn't happening.

I stuck here for two days please anyone can help me

[Note: Please don't mention in your answer that i should grouped my routes in web middleware. ]


Solution

After digging very deep in laravel i finally found what i was doing wrong. And i am posting may be it help some in future.

Important thing :- Laravel save session very last in its request life-cycle. It saves session it sends header response. So if we echo something in controller class then it will send header response without doing saving session and our session will not save. In my case i use dump function in my controller which terminate the laravel default life-cycle and forcefully send header response to browser. that's why all of session data is lost. i remove dump() form my code and everything start working correctly



Answered By - sunny kashyap
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home
View mobile version

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing