3
votes

So facebook changed the way websites get the user profile image, all the details are here: https://developers.facebook.com/docs/graph-api/reference/user/picture/

So me and also SOF get the profile image of a user from facebook like this: https://graph.facebook.com/1108834579148558/picture?type=large

Now we get the default image facebook provides.

In facebook docs they write we need to attach Access Token in order to get the user profile image from now, How does it work?

The only thing I can think of is upon user login facebook can retrieve the user profile image, does anyone can help with this, I am using .Net core.

1

1 Answers

5
votes

Facebook explains the new way of getting the User Image after October 2020 in their new docs here and they state the required changes as following:

This endpoint supports App-Scoped User IDs (ASID), User IDs (UID), and Page-Scoped User IDs (PSID). Currently you can query ASIDs and UIDs with no requirements. However, beginning October 24, 2020, an access token will be required for all UID-based queries. If you query a UID and thus must include a token:

1. Get an access_token in any form that facebook provides you

Depending on your application structure you would use either one of the following methods provided by Facebook to gain an access_token. You can find more about access_token on the FB docs here.
App Access Token
Client Access Token

As an Example for the Client Access Token which I am using:
Make a GET Request to https://graph.facebook.com/oauth/access_token with the following parameters:

[
   "client_id"     => #FACEBOOK_CLIENT_ID, 
   "client_secret" => #FACEBOOK_CLIENT_SECRET, 
   "grant_type"    => "client_credentials",
]

As Response you will get your access_token which you need to attach on the new Image URL.

2. Get the full avatar URL with the access_token attached.

As of 2020 October 23 this is working for me. The Full Image format is now
{$this->graphUrl}/{$this->version}/{$userID}/picture?type=large&redirect=false&access_token={$access_token}

If you set redirect=false you will get a JSON Object as Response:

{
    "data": {
        "height": 100,
        "is_silhouette": false,
        "url": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=10152700727498624&height=100&width=100&ext=1606081666&hash=AeTQyGgugiSbRcB7Sxw",
        "width": 100
    }
}

In the other hand if you leave redirect=true or doesn't set it at all you will get the Image itself which you can then save on your disk or use the url as the image path. But I am not sure if that given URL is long lived or not. I got the same URL working for almost one Week now, so I think that URL will stay as it is once you have requested for it with an valid access_token.

Example Request in PHP

As I have implemented that in PHP I cannot give you an example code but show you the way I've done it with the Guzzle Client within the Laravel Framework. You can have a look into my upgraded Provider Class for Laravel Socialite here.

    public function getAccessToken(){
        // Make a request to get the Access Client
        $res = Http::get("https://graph.facebook.com/oauth/access_token", [
            "client_id"     => config('services.facebook.client_id'),
            "client_secret" => config('services.facebook.client_secret'),
            "grant_type"    => "client_credentials",
        ]);

        // Response is a JSON Object, so decode it into an Array
        $r = $res->json();

        // Return the access_token Array Key out of the response
        return Arr::get($r, 'access_token', false);
    }


    public function getFacebookAvatar(array $user){
        // get the access_token from the above method
        $access_token = $this->getAccessToken();

        // build the new URI path for the User Image
        $path = "{$this->graphUrl}/{$this->version}/{$userID}/picture?type=large&redirect=false&access_token={$access_token}";
        $res  = Http::get($path);
        
        // Get the final User Image URL out of the response
        return Arr::get($res->json(), 'data.url', false);
    }

Quick and dirty way to build your own Access Token (not recommended)

There is one way to build your own access_token but this should be used only for testing purposes due the fact you are providing your full credentials and that could be hijacked. You can archieve that by building a concatened string with your credentials and the | as delimiter in this format: {cliend_id}|{client_secret}.