I am using the v6 C#.Net Facebook SDK (a blog can be found http://blog.prabir.me/post/Facebook-CSharp-SDK-Writing-your-First-Facebook-Application-v6.aspx).
I need to receive access permission to offline_access from users and later on (different session) post images to that user.
I've also tried uploading images to a certain page (of mine) but couldn't.
I am providing a simple dialog for the user and accept his allow for all the credentials I am asking for "user_about_me,read_stream,user_online_presence,friends_online_presence,offline_access,publish_stream,photo_upload"
Than, in different session (restarting my application), I am creating an access token using the following method:
(using WebRequest as followed:)
var url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials",AppId, AppSecret);
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
var myString = (new StreamReader(webResponse.GetResponseStream()).ReadToEnd());
myString = myString.Replace("access_token=", "");
However when trying to access a user, that has previously gave an offline_access credentials, using the access token I get exception thrown:
(OAuthException) An access token is required to request this resource
for a very simple request:
var fb = new FacebookClient(myString);
var result = fb.Get("/{0}/permissions", userThatGaveCredentials);
Is it possible to achieve what I am looking for and if so, what am I doing wrong?
Your code to request the access token the second time is not working. There is no reason to do this (and it wont always work anyway). You should just save the access token from when the use logs in the first time.
The error you are receiving is because your myString is null when you pass it into FacebookClient, thus the error that you are not providing an access token.
Also, you should note that offline_access is being deprecated and will be removed in a few weeks so you shouldn't build a new app that uses it anyway.
Related
I got some of the APP's APIs.
When I use the browser to access these APIs, the browser popup window tell me to fill in the username/password, Then I tried to fill out my username/password and found that I passed the verification!
Then I tried to write the code
var myClientHandler = new HttpClientHandler();
myClientHandler.Credentials = new NetworkCredential("abc", "!##");
this._client = new HttpClient(myClientHandler);
this._client.BaseAddress = new Uri("http://api.xxx.com");
var result = await this._client.GetStringAsync("some_api_foo.json");
Run well!
(We know that if there are no NetworkCredential, there will be 401 unauthorized exception)
But I found out that the official APP could access some of the APIs without the user logging in. How does it work? Does it use a public account? Or is there another way to access the APIs?
It uses Windows integrated authentication (Kerberos) to authenticate your users without asking them for credentials
Use Fiddler >check Authorization Header is present: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxx is Username:Password(Base64)
Decrypt it!
I'm working on a new Universal App (first time) and I am trying to use Login with Amazon as my authentication provider. Amazon doesn't provide an SDK for .NET for LWA so I'm left trying to figure it out on my own.
Here is what I am doing so far:
var redirectUrl = "https://localhost/";
var baseUrl = "https://amazon.com/ap/oa?client_id=MY_CLIENT_ID&response_type=code&scope=profile";
var uri = new Uri(baseUrl);
var redirectUri = new Uri(redirectUrl);
WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, uri, redirectUri);
This gets me to the login with Amazon page just fine, and allows me to login, but handing off back seems to be a problem.
Any and all help appreciated.
Amazon LWA Developer Guide
Page 25.
As I can see you missed some required parameters - scope and redirest_uri. Specify them properly and probably it will work.
For a Universal App, make sure you enable the Internet Client & Server Capability.
I haven't used WebAuthenticationBroker and you haven't provided the error message you're getting, so I have to do some guessing here...
Scanning the MSDN docs for WebAuthenticationBroker, it looks like it's meant to work with the Implicit grant flow (where an access token is returned after login/consent) vs. the Authorization grant flow (where you get back a code you must then exchange for an access token).
So if it's getting back an Authorization grant response instead of an Implicit grant response, it could be throwing an error because it's missing expected fields.
Try changing your response_type from code to token and see if that helps. If it doesn't, please post some more detail on the error you're getting.
I have made a web app that tries to create a page access token that never expires. It does this because it's all written in PHP, and needs access to the data without asking the user to login repeatedly.
The Facebook docs say this:
To get a longer-lived page access token, exchange the User access token for a long-lived one, as above, and then request the Page access token. The resulting page access token will not have any expiry time.
And so I have written the following PHP:
// get our current access token
$accessToken = $session->getAccessToken();
// make it a long-lived access token
$longLivedAccessToken = $accessToken->extend();
// find the list of pages we have access to
$request = new FacebookRequest($session, "GET", "/me/accounts?fields=name,access_token,perms");
$response = $request->execute()->getGraphObject()->asArray();
// get the first page access token
$pageAccessToken = $response["data"][0]->access_token;
This seems to work: the access token debugger says the token never expires and is valid right now. I can even use this token to do many things.
But my token cannot do some things, and I don't know why.
Where I am hitting the problem is reading the /insights/page_fans_country/lifetime end point.
If I use /mypage/insights/page_fans_country/lifetime I get a response. That is, mypage is the page that was used to generate the permanent access token.
If I use /otherpage/insights/page_fans_country/lifetime I get no data.
As far as I know, this is public data – if I generate a new access token in the Graph API explorer, I get valid data for both requests.
So:
1) Am I requesting the permanent page token correctly?
2) Is this just a limitation of (permanent) page tokens – that they cannot access some public data?
3) If so, is there a correct way of accessing this data using tokens that don't expire?
I have been requested by a client to pull the latest posts from their LinkedIn group to one of our website pages.
I am developing using ColdFusion 9 and have been researching this for quite a few days now and decided to post my query here in the hopes that someone will be able to help me out.
I can get to the point where I have a requestToken. My understanding is that I now need to sign the request token to get the accessToken. My problem is that I need to do this behind-the-scenes. However, all the examples that I can find are redirecting the front-end user to the authorisation url to allow the user to authenticate, but I don't want the user to authenticate, I want to authenticate server-side instead.
I am trying to use the Scribe Java wrapper library. Below is the code that I have so far which gets the requestToken (as well as the authorisation url). I need someone to point me in the right direction to sign the token on the server-side code so that I can make the necessary calls to consume the Groups API (e.g. http://api.linkedin.com/v1/groups/{id}/posts?count=5&start=1)
<cfscript>
var l = {};
//The LinkedIn public and private keys for application
l.oauth_consumer_key = "[My public key]";
l.oauth_sign_key = "[My secret key]";
l.serviceBuilder = CreateObject("java","org.scribe.builder.ServiceBuilder");
l.LinkedInApiClass = CreateObject("java", "org.scribe.builder.api.LinkedInApi").getClass();
l.service = l.serviceBuilder.provider(l.LinkedInApiClass).apiKey(l.oauth_consumer_key).apiSecret(l.oauth_sign_key).callback("[My callback url]").build();
l.requestToken = l.service.getRequestToken();
l.authUrl = l.service.getAuthorizationUrl(l.requestToken);
// I NEED TO DEFINE WHAT TO DO AT THIS POINT TO SIGN THE REQUEST SERVER SIDE
...
...
</cfscript>
Kirsten is technically correct - Linked In Api's require user authentication. It's annoying because you need to authenticate to even retrieve group posts.
However there are ways round it.
With scribe you can manually create an access token. So what I would do is create a dummy user account on Linked In, authenticate that user as normal and save the returned signed credentials on your database, which you can then use to create the token:
var accessToken = createObject("java", "org.scribe.model.Token").init(
"singedTokenStringReturnBackFromLinkedIn",
"singedSecretStringReturnBackFromLinkedIn",
"oauth_token=singedTokenStringReturnBackFromLinkedIn&oauth_token_secret=singedSecretStringReturnBackFromLinkedIn&oauth_expires_in=0&oauth_authorization_expires_in=0"
);
You can then skip the authenticate part and call the api allowing you to display the group posts without the current user having to sign in:
var req = createObject("java", "org.scribe.model.OAuthRequest").init(
createObject("java", "org.scribe.model.Verb").GET,
"http://api.linkedin.com/v1/groups/123456/posts"
);
oAuthService.signRequest(accessToken, req);
I have no idea if this would violate Linked In's T&C though.
OAuth authentication is designed for the user to give their permission to the application via a login on the site (in this case LinkedIn). It is not designed for you to automatically have the user grant permission for your application.
In order to get an access token to use the LinkedIn APIs, you have to include the part of the authentication flow that sends the user to LinkedIn to give your application permission to act on their behalf, at which point you can retrieve a verifier token either via PIN (which the user inputs) or via a callback to your application.
In short, there is no way to "authenticate server-side" without having the user interact with the LinkedIn site.
I'm building a web application and I'm using OAuth to provide Facebook authentication. I've successfully generated an access_token and each time the user logs out/back in, I match their access_token to find their account. This works very well.
In addition, I'm building a Windows Phone 7 companion app. I've got the same process for authentication, using the Facebook SDK, but the access_token that is returned is different. This means I cannot match the account.
Since the logout/login to my web application appears to generate the same access_token repeatedly, I'm confused as to why the mobile app generates a different access token.
Can anyone tell me if the behaviour I'm expecting is correct? I've scoured the Facebook documentation, but can't find anything relevant. Maybe OAuth isn't the correct thing to do here.
Each time I logged in, the code would return a different access_code value. I needed to add a new field called "response_type" with a value of "code". This then redirected me to the login page and responded with the correct token, which I then exchanged for an access code.
To generate the URL, this was the code:
Facebook.FacebookOAuthClient client = new Facebook.FacebookOAuthClient();
client.AppId = "285539721457932";
client.AppSecret = "65233641cf71e6fa9fef5ecd7d802ebf";
client.RedirectUri = new Uri("http://www.imaybelate.com/Account/FacebookCallback");
url = client.GetLoginUrl(new Dictionary<string, object>()
{
{ "display", "wap" },
{ "response_type", "code" },
{ "permissions","offline_access"}
}).ToString();