Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

szacchino's avatar

Socialite Logout

Hi everybody,

I'm new to laravel (using 5.1) but I was able to create a starter site with both traditional authentication, using username/pwd, and facebook authentication, using oauth and socialite. In the latter case I followed the implementation suggested in this tutorial: http://www.codeanchor.net/blog/complete-laravel-socialite-tutorial/ In both cases the user is able to login succesfully.

Now if users with traditional auth logout, everything goes well, the session expires. Unfortunately, the only way I found to logout users authenticated through facebook was by the means of Facebook logout button: this button logs users out of facebook.com and also from my webapp. Using the classic auth/logout route for oauth users does not log them out.

I'd prefer a way to logout oauth users from my webapp without exiting from facebook.com session: or maybe it's better to say how to deauthorize usage of facebook account? Any suggestions?

Thank you in advance

Sandro

0 likes
3 replies
szacchino's avatar
szacchino
OP
Best Answer
Level 1

Perhaps it's not the most elegant solution but currently it works. Please refer to a new laravel app built as suggested in the blog article cited in my previous post before using the following code. The deauthorization of the webapp from facebook is obtained calling an HTTP DELETE (nor GET or POST) on an url like the following:

    https://graph.facebook.com/v2.4/me/permissions?access_token=<access_token_stored_in_db>

The AuthController now has a method facebooklogout used to deauthorize my facebook app. In the following the code I inserted:

In vendor\laravel\socialite\src\Two\FacebookProvider.php added:

    protected function getDeauthUrl($access_token)
    {
        return $this->graphUrl.'/'.$this->version.'/me/permissions?access_token='.$access_token;
    }

In vendor\laravel\socialite\src\Two\AbstractProvider.php added:

    abstract protected function getDeauthUrl($state);
    
    public function deauthorize($access_token)
        {           
            $url = $this->getDeauthUrl($access_token);
            $response = $this->getHttpClient()->delete($url);
        }

WRT the blog article cited in previous post, in AuthenticateUser.php:

    public function deauthorize($listener, $provider) {
            if(\Auth::check()) {
                $this->socialite->driver($provider)->deauthorize(\Auth::user()->access_token);
            \Auth::user()->access_token = '';
                \Auth::user()->save();
                $this->auth->logout();   
                return $listener->userHasLoggedOut();
            }
        }

and in AuthController.php:

    public function __construct()
        {
            $this->middleware('guest', ['except' => ['getLogout', 'facebooklogout']]);
        }   

    public function facebooklogout(\App\AuthenticateUser $authenticateUser, Request $request, $provider = null)  {
            return $authenticateUser->deauthorize($this, $provider);    
        }

        public function userHasLoggedOut() {
            return 'Logout completed';
        }

There are also some lines in UserRepository.php used to store the access_token in the db:

<?php
namespace App\Repositories;

use App\User;

class UserRepository {
    public function findByUserNameOrCreate($userData) {
        $user = User::where('provider_id', '=', $userData->id)->first();
        if(!$user) {
            $user = User::create([
                'provider_id' => $userData->id,
                'name' => $userData->name,
                'username' => $userData->nickname,
                'email' => $userData->email,
                'avatar' => $userData->avatar,
                'active' => 1,
                'provider' => 'facebook',
                'access_token' => $userData->token,
            ]);
        }

        $this->checkIfUserNeedsUpdating($userData, $user);
        return $user;
    }

    public function checkIfUserNeedsUpdating($userData, $user) {

        $socialData = [
            'avatar' => $userData->avatar,
            'email' => $userData->email,
            'name' => $userData->name,
            'username' => $userData->nickname,
            'access_token' => $userData->token,
        ];
        $dbData = [
            'avatar' => $user->avatar,
            'email' => $user->email,
            'name' => $user->name,
            'username' => $user->username,
            'access_token' => $user->access_token,
        ];
       
        if (!empty(array_diff($socialData, $dbData))) {
            $user->avatar = $userData->avatar;
            $user->email = $userData->email;
            $user->name = $userData->name;
            $user->username = $userData->nickname;
            if ($userData != '') {
                $user->access_token = $userData->token;
            }
            $user->save();
        }
    }
}

Obviously I added the access_token (text) field to the users table.

Any improvement to the above code will be very appreciated.

Bye

Bishwajit's avatar

@jasleow Exactly , I used the same way , invested 3 days , searching for the solution at last find the same solution, used guzzle and the delete from this end point without loading the page directly from controller

Please or to participate in this conversation.