Authentication Facebook C# SDK - c#

I have a website where i have a event module, where the users can maintain their own events.
At the same time i have a Facebook Page(not app) and i would really like to create/update/delete the events from my website directly to Facebook.
I have the following working:
FacebookClient clientApp = new FacebookClient(token);
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("name", currentEvent.HeadLine);
DateTime startTime = DateTime.Now;
DateTime endTime = DateTime.Now.AddDays(1);
parameters.Add("start_time", currentEvent.StartDateTime);
parameters.Add("end_time", currentEvent.EndDateTime);
parameters.Add("location", currentEvent.Location);
parameters.Add("description", currentEvent.Description);
var postResult = (IDictionary<string, object>)currentClient.Post("pageid/events", parameters);
the accesstoken used is from my facebook login, so if that expires the system fails.
Any other way or can i get a newer expiring accesstoken.
Regards Keld
regards Keld

You have two options, one is to request the permission offline access from Facebook when you obtain the token. This gives you a token that never expires (unless the user explicitly removes access for your app.
The second way is to handle exceptions from the callback of the method. In the handling code you detect a token expired exception and redirect users to the appropriate login page to get a new token. You can then re-try the event update.

Related

IdentityServer4 Refresh Token: How to determine expiration time?

I am working with the Identity Server 4 sample code. In particular, for the client I am using the sample MVC Client with the Hybrid flow: https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Clients/src/MvcHybrid
And for the server I am using Identity Server with in-memory clients (no Entity Framework, and no ASP.Net Identity): https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Quickstarts
Both client and server have pretty much vanilla, out-of-the-box configuration.
I am trying to understand how refresh tokens expire and how a native app can pro-actively determine the expiration time (before it gets rejected by an API). My understanding is that the default expiration for refresh tokens is long:
http://docs.identityserver.io/en/latest/topics/refresh_tokens.html:
Maximum lifetime of a refresh token in seconds. Defaults to 2592000 seconds / 30 days
However, when the sample code requests a refresh token, I do not get the expected expiration time. Here is the sample code:
var disco = await _discoveryCache.GetAsync();
if (disco.IsError) throw new Exception(disco.Error);
var rt = await HttpContext.GetTokenAsync("refresh_token");
var tokenClient = _httpClientFactory.CreateClient();
var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "mvc.hybrid",
ClientSecret = "secret",
RefreshToken = rt
});
tokenResult.ExpiresIn is 3600 seconds, which is actually the expiration of an access token. I was expecting that to be 2592000 seconds. So question #1 is: Why is this the case?
But more importantly, I know that the expiration for the refresh token is in fact the default 30 days when I use SQL Server as the data store. There is a table PersistedGrants that contains the refresh tokens, and the expiration is clearly 30 days from the issue date. So question #2 is: How can an app programmatically determine the expiration date of the refresh token it received?
I've tried to parse the RefreshToken itself, but it is not really a full JWT, so this throws an error:
var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessTokenResponse.RefreshToken);
var diff = jwt.ValidTo - jwt.ValidFrom;
I've also searched through the IdentityServer4 unit / integration tests and cannot find an example of introspecting a refresh token.
Presumably that information either needs to be somewhere in the initial token response, or there needs to be an endpoint built into Identity Server. But I can't find either of these things.
Ok, so the answer is that there is no data in the access_token response that indicates the expiration time of the refresh_token. Additionally, there is no endpoint that can be used to check the expiration.
The OAuth spec does not say anything about this, so I did not want to alter the access_token response. I wound up making my own endpoint that returns the expiration time if needed. Here is my controller action, if anyone needs a starting point:
private readonly IRefreshTokenStore _refreshTokenStore; // inject this into your controller
...
[Route("[controller]/GetRefreshTokenExpiration")]
[Authorize(...YOUR SCOPE...)]
public async Task<IActionResult> GetRefreshTokenExpiration(string refreshTokenKey)
{
var refreshToken = await this._refreshTokenStore.GetRefreshTokenAsync(refreshTokenKey);
if (refreshToken == null)
{
return NotFound(new { message = "Refresh token not found" });
}
return Ok(new {
message = "Refresh token found",
lifetime_seconds = refreshToken.Lifetime
});
}
When one calls ../token
We get access_token, expires_in, refresh_expires_in, refresh_token and other stuff
Decode access_token to get ValidTo substract expires_in from ValidTo and then add refresh_expires_in to ValidTo and that should give you the expiry date of the refresh_token.

How do I convert from an app token to a page token using the Facebook graph API?

I'm using the Facebook .NET SDK.
I can generate an app access like so:
var client = new FacebookClient();
dynamic appAccessToken =
client.Get(
string.Format("/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials", appId, appSecret));
which brings me back an access token in the format {appId}|{token}
If I then pass this back into the client object I hoped to get a page access token, but I'm just getting back the page Id, where I as expecting to get the page Id and an access token.
Full code:
var client = new FacebookClient();
dynamic appAccessToken =
client.Get(
string.Format("/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials", appId, appSecret));
client.AccessToken = appAccessToken.access_token;
dynamic tokens = client.Get(string.Format("/v2.5/{0}?fields=access_token", pageId));
To get a Page Token, you need to authorized with the manage_pages permission and use the /me/accounts endpoint to get Page Tokens for all your Pages. Or /page-id?fields=access_token for a single Page. You MUST use a User Token with manage_pages though, you can´t just use an App Token. App Tokens are not tied to a User (and the Pages he manages).
More information:
https://developers.facebook.com/docs/facebook-login/access-tokens
http://www.devils-heaven.com/facebook-access-tokens/
Make sure you understand the difference between App Token, User Token and Page Token. And of course you can´t get a Page Token for Pages you don´t manage, just in case it´s not clear.

tweetsharp - app stops being able to tweet after a few hours

I have a asp.net 4.5 webforms site that allows users to link their account to twitter and tweet directly from my site.
My app is registered with twitter and I am able to successfully authorise my app for the user's account and initially can tweet fine, but after a few hours the tweets stop working. I am using tweetsharp to handle the authorisation.
my code is:
TwitterClientInfo twitterClientInfo = new TwitterClientInfo();
twitterClientInfo.ConsumerKey = ConsumerKey;
twitterClientInfo.ConsumerSecret = ConsumerSecret;
var requestToken = new OAuthRequestToken { Token = oauthtoken };
TwitterService twitterService = new TwitterService(ConsumerKey, ConsumerSecret);
OAuthAccessToken accessToken = twitterService.GetAccessToken(requestToken, oauthverifier);
twitterService.AuthenticateWith(accessToken.Token, accessToken.TokenSecret);
TwitterUser user = twitterService.VerifyCredentials(new VerifyCredentialsOptions());
SendTweetOptions options = new SendTweetOptions();
options.Status = tweetText;
twitterService.SendTweet(options);
what i have noticed is that while the app is successfully tweeting, the accessToken.Token value that is being used to authenticate the user has a proper value (a long string of numbers and upper/lowercase characters) however when it stops tweeting the accessToken.Token value is just a single question mark "?".
Twitter says it doesn't expire tokens so i am at a loss to understand what is happening or how it can be resolved? if i went in to my twitter account and deauthorised my app and went through the authorisation again it would work fine for a few hours, but obviously that's not something i can ask my users to do.
can anyone suggest a resolution to this - either to stop the accessToken value becoming ? or to handle it and get a proper value if it does (without reauthorising the app)
Well, without beginning to understand the actual issue, I managed to fix it
Instead of retrieving the access token every time via:
var requestToken = new OAuthRequestToken { Token = oauthtoken };
OAuthAccessToken accessToken = twitterService.GetAccessToken(requestToken, oauthverifier);
twitterService.AuthenticateWith(accessToken.Token, accessToken.TokenSecret);
i only do that once and store accessToken.Token and accessToken.TokenSecret in the database and retrieve them when tweeting and supply them
twitterService.AuthenticateWith(accessTokenFromDB, accessokenSecretFromDB);
I have seen somewhere that Twitter doesn't expire tokens, so this should work. Certainly it's been working for me all weekend whereas the original code would stop working after a few hours.
Thought this might help some others who have the same issue.

Handle facebook expiration token

I am having some trouble while integrating facebook API with my desktop application.
Now, I`m trying to use Facebook SDK for .NET: http://facebooksdk.net/
Here is the problem:
When I use my tokens, Facebook returns the following message:
"Error validating access token: Session has expired at unix time 1365165488. The current unix time is 1378218499."
I saw in some posts that I can do something like this to renew my access token:
Dictionary<string, object> fbParams = new Dictionary<string, object> ();
fbParams["client_id"] = token.appId;
fbParams["grant_type"] = "fb_exchange_token";
fbParams["client_secret"] = token.appSecret;
fbParams["fb_exchange_token"] = token.accessToken;
JsonObject publishedResponse = fbClient.Get ("/oauth/access_token", fbParams) as JsonObject;
return publishedResponse["access_token"].ToString ();
But it doesn't work; it throws another exception with the same message ("Session has expired...")
Is there an easy way to do this?
I don't know if this can impact my application but this access token is like 1 year old (and I'm using in a desktop application).
Thank you very much! =)
The message is clear, you are using a token that has already expired (It's actually over four months old). You need to go back through the login flow with a user arriving at an authorization screen.
You cannot extend a token that has already expired, you can only extend tokens that are valid. e.g. a short lived (two hours) token to a long lived token (two months)

Get Facebook's Application Access Token

I have to use Facebook's notification for my web app.
Facebook Graph API requires the Application Access Token for this action.
Is there a way to get this token by code (C# SDK) or is this generated by Facebook a single time?
Is this token static (and secret) or with expire datetime?
For info: https://developers.facebook.com/tools/access_token/ - App Token, not User Token!
Thanks
The answer is the dynamic way by code:
var fb = new FacebookClient();
dynamic result = fb.Get( "oauth/access_token", new
{
client_id = <myAppID>,
client_secret = <mySecretID>,
grant_type = "client_credentials"
} );
var apptoken = result.access_token;
Or by the combination or appid|secretid
You can just use the concatenation of id and secret with a pipe symbol in the middle:
app_id|app_secret
This is actually how the PHP SDK creates the app access token internally, so there should be no question about the reliability of this method. (From other endpoints where you actively query for an app access token you might get another token that does not match this scheme though.)
you can investigate the getApplicationAccessToken method as in another c# sdk project from github
https://github.com/barans/FacebookCsharpSdk/blob/master/FacebookCSharpSDK/FacebookClient/FacebookClient.cs

Categories