How to get Facebook Friend List in ASP.NET? - facebook

I'm building an App with ASP.NET MVC 5 and Identity.
So far the login is working correctly.
Here the auth:
var fb = new FacebookAuthenticationOptions();
fb.Scope.Add("email");
fb.Scope.Add("friends_about_me");
fb.Scope.Add("friends_photos");
fb.AppId = "";
fb.AppSecret = "";
fb.Provider = new FacebookAuthenticationProvider() {
OnAuthenticated = async FbContext => {
FbContext.Identity.AddClaim(
new System.Security.Claims.Claim("FacebookAccessToken", FbContext.AccessToken));
}
};
fb.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
app.UseFacebookAuthentication(fb);
I'm trying to get the friends list. I've been looking for a few examples but none is working with this version of MVC 5.
My question is. How can I fetch all the friends with this version?
I don't want to use Javascript API, I want all the code in c# and then send to the view.
I think I just need to rewrite the login and store the access token in the session, and then simply call var client = new FacebookClient(TOKEN);
So how can I rewrite the login?

You've already got everything you need. The OnAuthenticated callback you've set adds a claim containing the access token for Facebook. You just need to pull the claim for the user:
var identity = (ClaimsIdentity)User.Identity;
var facebookClaim = identity.Claims.FirstOrDefault(c => c.Type == "FacebookAccessToken");
if (facebookClaim != null)
{
// access facebook API with `facebookClaim.Value`
}
And if it exists, then you can use the Facebook API to pull in their friends by making standard HTTP calls via something like HttpClient.

Related

ASP.NET Core Facebook Authentication Middleware user picture

I'm trying to retrieve user profile picture with Facebook Authentication middleware in ASP.NET Core 1.0. I have managed to add these configurations to make the user picture availble
app.UseFacebookAuthentication(new FacebookOptions()
{
AppId = Configuration["Authentication:Facebook:AppId"],
AppSecret = Configuration["Authentication:Facebook:AppSecret"],
Scope = { "public_profile" },
Fields = { "picture" }
});
and to retrieve data
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
and
var userName = info.Principal.FindFirstValue(ClaimTypes.GivenName);
But How can I now retrieve user picture as there is not Claim Type for it?
As Set said in his answer you can get the picture using the Facebook Graph API like this https://graph.facebook.com/{user-id}/picture.
Example code :
var info = await _signInManager.GetExternalLoginInfoAsync();
var identifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var picture = $"https://graph.facebook.com/{identifier}/picture";
You might want to check if info is not null and if info.LoginProvider is facebook.
Yes, in general, the standard (oauth) implementation of UserInfo Endpoint may return picture in response if you specify Fields = { "picture" }.
Facebook Graph API provides https://graph.facebook.com/v2.6/me as UserInformation endpoint and ASP.NET Core Facebook Auth Middleware uses it for claims population.
The problem is that Facebook Graph API doesn't return picture in response if you use this \me endpoint. They did so before but for some reason have removed that. Related SO: facebook oauth, no picture with basic permissions
But you can get the picture using:
https://graph.facebook.com/USERNAME/picture
In my project ASP.NET Core 2.2 I use this code:
services.AddAuthentication()
.AddFacebook(options =>
{
options.AppId = Configuration["Authentication:Facebook:AppId"];
options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
options.Events.OnCreatingTicket = (context) =>
{
var picture = $"https://graph.facebook.com/{context.Principal.FindFirstValue(ClaimTypes.NameIdentifier)}/picture?type=large";
context.Identity.AddClaim(new Claim("Picture", picture));
return Task.CompletedTask;
};
});
And in Controller, in ExternalLoginCallback action I retrieve value this way:
var info = await _signInManager.GetExternalLoginInfoAsync();
var picture = info.Principal.FindFirstValue("Picture");

Azure Mobile Services backend serviceUser does not return Facebook identities as expected

I'm struggling with a Xamarin Forms (iOS)/Azure Mobile Services/Facebook issue that I don't know how to resolve. What I'm trying to do is login to Facebook using AMS and then save that user's details to a service side database via a custom controller. I am running Azure Mobile Services on the backend.
What I have in place is the code below that successfully logs in a Facebook user.
var fbUser = await DependencyService.Get<IMobileClient>().LoginAsync(MobileServiceAuthenticationProvider.Facebook);
I then want to save fbUser to the database where I'm using ASP.NET Identity tables all configured. I want to use this user to gain access to the facebook user's profile information. I therefore have a backend service custom controller action that looks like this:
[Route("logintofacebook")]
[AuthorizeLevel(AuthorizationLevel.Anonymous)]
public async Task<IHttpActionResult> LoginToFacebook(MobileServiceUser msUser)
{
try
{
if (msUser != null)
{
var serviceUser = User as ServiceUser;
var identities = await serviceUser.GetIdentitiesAsync();
var result = new JObject();
var fb = identities.OfType<FacebookCredentials>().FirstOrDefault();
if (fb == null)
{
return NotFound();
}
var googleCredentials = identities.OfType<GoogleCredentials>().FirstOrDefault();
var azure = identities.OfType<MicrosoftAccountCredentials>().FirstOrDefault();
var accessToken = fb.AccessToken;
result.Add("facebook",
await GetProviderInfo("https://graph.facebook.com/me?access_token=" + accessToken));
var email = GetUserInfo(result);
var userTypeId = UTypes.Facebook;
When debugging on the backend side, the MobileServiceUser is a valid object and I can check the token and Facebook userid which are the same as were created on the client. However, the highlighted line returns zero identities. This means that fb variable end up being null.
The question is, why are no identities being returned from the serviceUser variable above?
Here's what the debugged AMS token looks like when debugged with jwt.io
{
"iss": "urn:microsoft:windows-azure:zumo",
"aud": "urn:microsoft:windows-azure:zumo",
"nbf": 1446872000,
"exp": 1449464000,
"urn:microsoft:credentials": "{\"accessToken\":\"CAAL2gwRM4RYBAKV9Wp0Evjp2aATnm5OIHHc15ujJfeevqCW6DoI36HOQCOYq96xUjZA6VXwovnkBOlY0SkC9nrdwr8jdbF3qJdtK4GAHVk9SGxKVYUZBJ4UwPqQmb5yka93GzL0Fl86m93LnqTffIPJ6vkMfpP0ZAroKzmcJxM1pJ7BAAAA\"}",
"uid": "Facebook:0000000000000000",
"ver": "2"
}
(I've replaced out the facebook section with zeros)
thanks
O

facebook c# SDK get albums and images

what i am trying to achieve should be simple by theory but hell by implementation, if you think otherwise please help.
so what i am trying to achieve here is that I have my facebook page which I created a developer acount for it, and what i want is to take albums from the page to my website.
I am using the latest stable facebook sdk for .net 6.8.0, and i am assuming that the graph api is on v2.2.
this is the code i am using below to get the access token and access my albums
try
{
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new
{
client_id = "---my application number---",
client_secret = "---my application secret---",
grant_type = "client_credentials"
});
var fb2 = new FacebookClient(result.access_token);
dynamic albums = fb2.Get("my application number/albums");
foreach (dynamic albumInfo in albums)
{
try
{
dynamic albumsPhotos = fb2.GetTaskAsync(albumInfo.id + "/photos");
}
catch (Exception Exception)
{
throw Exception;
}
}
}
catch (Exception e)
{
throw e;
}
The data returned in the dynamic albums variables is empty, the thing that confused me more is when i use facebook graph api explorer the call work fine and it return the albums. so what exactly i am missing.
I also read in some threads that you can access your albums without the secret password if they are public but that didn't work for me either i tried it in javascript but no joy.
Thank you in advance.
Since this is your page, it should be pretty easy to retrieve your own photos using Windows PowerShell and http://facebookpsmodule.codeplex.com Get-FBAlbums.

Retriving Facebook posts from Profile via FB api

I have registered an app in facebook developers program and I can retrieve posts from facebook page using fb api, but I cannot retrieve posts from facebook profile. Should I use some different access token for both page or profile? Is there a different way for retrieving posts from facebook page and profile?
Any help will be appreciated!
You may need the user_status permission.
And you call the posts using this graph query {USER_ID}?fields=statuses
Prerequisite:- You need to have valida FB token for all the request:-
I am answering using c# language.
Step 1:- First you need to get the user's FB id using FB token
I am using Facebook SDK 7.0.6 for querying purpose
here's how to initialize the FB service which we will use in our consecutive calls.
FacebookService facebookService = new FacebookService(facebookToken);
var _facebookClient = new Facebook.FacebookClient(token);
Code snippet
public string GetFacebookID(string facebookToken)
{
dynamic result = _facebookClient.Get("me?fields=id");
if (result.ToString().Contains("id"))
{
return result["id"];
}
return string.Empty;
}
after that you can execute below method to get user's post using FB ID and token
public List<Post> GetPostsForUser(string facebookID)
{
List<Post> posts = new List<Post>();
dynamic result = _facebookClient.Get(facebookID + "/posts"); //Case Sensitive, Posts doesn´t work
if (result.ToString().Contains("data") && result.data.Count > 0)
{
foreach (var item in result.data)
{
posts.Add(new Post
{
ID = item.id,
Story = item.story,
Message = item.message,
Created_Time = Convert.ToDateTime(item.created_time),
Reactions = GetReactions(item.id)
});
}
result = _facebookClient.Get(GetNextURL(result.ToString()));
}
return posts;
}

Using Facebook Requests 2.0 with the C# SDK

I am trying to update the bookmark count field with the SDK but have not had any success yet.
Can somebody tell me what classes I need to instantiate to do something similar to the following link:
http://developers.facebook.com/blog/post/464
Note:
The link demonstrates how to set the bookmark count and delete it. I would like to be able to do the same with the SDK, any help would be appreciated.
To do this, first you need to get you app's access token:
private string GetAppAccessToken() {
var fbSettings = FacebookWebContext.Current.Settings;
var accessTokenUrl = String.Format("{0}oauth/access_token?client_id={1}&client_secret={2}&grant_type=client_credentials",
"https://graph.facebook.com/", fbSettings.AppId, fbSettings.AppSecret);
// the response is in the form: access_token=foo
var accessTokenKeyValue = HttpHelpers.HttpGetRequest(accessTokenUrl);
return accessTokenKeyValue.Split('=')[1];
}
A couple of things to note about the method above:
I'm using the .Net HttpWebRequest instead of the Facebook C# SDK to grab the app access_token because (as of version 5.011 RC1) the SDK throws a SerializationException. It seems that the SDK is expecting a JSON response from Facebook, but Facebook returns the access token in the form: access_token=some_value (which is not valid JSON).
HttpHelpers.HttpGetRequest simply uses .Net's HttpWebRequest. You can just as well use WebClient, but whatever you choose, you ultimately want to make this http request:
GET https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials HTTP/1.1
Host: graph.facebook.com
Now that you have a method to retrieve the app access_token, you can generate an app request as follows (here I use the Facebook C# SDK):
public string GenerateAppRequest(string fbUserId) {
var appAccessToken = GetAppAccessToken();
var client = new FacebookClient(appAccessToken);
dynamic parameters = new ExpandoObject();
parameters.message = "Test: Action is required";
parameters.data = "Custom Data Here";
string id = client.Post(String.Format("{0}/apprequests", fbUserId), parameters);
return id;
}
Similarly, you can retrieve all of a user's app requests as follows:
Note: you probably don't want to return "dynamic", but I used it here for simplicity.
public dynamic GetAppRequests(string fbUserId) {
var appAccessToken = GetAppAccessToken();
var client = new FacebookClient(appAccessToken);
dynamic result = client.Get(String.Format("{0}/apprequests", fbUserId));
return result;
}
I hope this helps.