I'm building a manual login flow for my App which is integrating some facebook functionality.
I need to check when the current access_token of the user will expire.
The API documentary says I should do this call:
GET graph.facebook.com/debug_token?
input_token={token-to-inspect} &access_token={app-token-or-admin-token}
So I did this in C#:
Uri inspectAccessTokenUri = new Uri("http://graph.facebook.com/debug_token?input_token="+access_token+"&"); //IDK which value should have the last parameter
HttpWebRequest checkToken = (HttpWebRequest)WebRequest.Create(inspectAccessTokenUri);
var response = await checkToken.GetResponseAsync();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string data = reader.ReadToEnd();
Debug.WriteLine(data);
The last parameter should be the app-token:
BUT: Of course I looked up how to get the app-token and facebook says:
Note that because this request uses your app secret, it must never be
made in client-side code or in an app binary that could be decompiled.
It is important that your app secret is never shared with anyone.
Therefore, this API call should only be made using server-side code.
(Facebook Graph API Documentation 1.1.16)
So my question: Can I check the token without the app-token or hardcoding the app-secret?
App secret is usually used by the server-side app, we don't use it in our UWP app, it could be decompiled.
Read the official doc about FB Graph Debug-Token, this can only be used when you debug your app, for example if you want to check the metadata about a given access token, after you publish your app, your code will not relay on it.
In an UWP app, we use WebAuthenticationBroker class to connect to OAuth providers such as Facebook, Flickr, Google, and Twitter. Maintenance is need during using OAuth connections. For example, expires information is included in the access token, when we use OAuth protocol for authentication and authorization, we need to refresh the access token after it expired.
Due to these conditions, you may reconsider what you can do in an UWP app and which API you should choose.
If the app-token is expired you will get a facebook response error. And you can catch this exception to deal with the situation you want. In this way you don't need to make a request with your app secret.
You can also use fb-uwp sdk that contains AccessTokenData for authenticated users
Related
This page claims that you can access the Places Graph functionality without having a logged-in user:
You make your calls using a Client Token (from the client), and an App Access Token (from the server).
The documentation regarding Client Tokens says:
The client token is an identifier that you can embed into native mobile binaries or desktop apps to identify your app. The client token isn't meant to be a secret identifier because it's embedded in apps.
This sounds like exactly what I want--I am trying to build a website that allows users to search for Facebook places. I need to be able to build the list using an AJAX request from the client side.
I can't for the life of me find any documentation on using the Client Token to make such a request.
Please note that I cannot use an App Token because this will be deployed to a website, and Facebook specifically says not to use App Tokens in that context.
I've tried using the Client Token directly as the access_token, but then I get Invalid OAuth access token.
How can I use the Client Token to make a Places Graph API call directly to Facebook's API from the client's browser?
Note: I realize that I could send the request to my own server, then relay that request from my server to Facebook, but that is not an optimal solution for me.
In case anyone is still struggling with this like I was. You just need to use the appId and client token joined with a pipe. So "appId|clientToken".
I would like to get basic user information from Facebook after the user has logged in.
I've looked at the documentation in How to: Work with authentication and under the "How to: Retrieve authenticated user information" section, it shows how to do it from the .NET backend code by using an HttpClient to make the call with the AccessToken:
var fbRequestUrl = "https://graph.facebook.com/me/feed?access_token="
+ credentials.AccessToken;
Since the mobile client has the accessToken that we get from MobileServices, can the client make the call directly to a Facebook endpoint, or does the client SDK provide us with any built-in functionality?
I've been following the Xamarin.Forms Sport project and the way they get the user information from Google is by hard-coding the Google endpoint and making a call to get the user info.
Note: Xamarin.Forms Sport uses Mobile Services, not Mobile App, so not sure if that makes any difference.
It sounds like you're doing the server-directed login: where you are making a call to your backend to do the login dance with Facebook. In this, your client application is making a GET call to .auth/login/facebook, which opens up a browser or the Web Authentication Broker where you enter your credentials. The end result is you will receive a Zumo access token (different from Facebook access token).
You cannot use the Zumo access token to access Facebook APIs by itself. In the "How To:" you linked, we show you how to use GetAppServiceIdentityAsync from the backend to get the Facebook access token. This is possible because you have stored your Facebook client ID via portal, which is available to the backend.
The advantage of doing auth like this was that you don't have to deploy your Facebook Client Id with your mobile apps. If you wanted to access the Facebook APIs from the client, though, you'll need to get the Facebook token to the client.
Few ways I can suggest:
Call .auth/me from your client. The response will give you a JSON object you can parse that should include the FB token associated with your Zumo token.
Write a custom API with [Authorize] attribute set that will perform GetAppServiceIdentityAsync and respond with the value of the facebook access token. You can then parse the response from your client. This is basically what .auth/me does, but you can write it to give back only your FB access token.
Use the Facebook .NET SDK http://facebooksdk.net/ to do client-directed login. You will get a Facebook token on your client, and then you can use our LoginAsync(Facebook, access_token) method to get a Zumo token so that your client can access both Facebook and your Mobile App backend. The disadvantage, as I mentioned before, is that you'll have to deploy your FB Client ID with your app.
Let's say I have an AngularJS application that consumes the REST API of a Django application.
The Django application has got a built-in OAuth2 provider that can be called to retrieve an access token and use the protected endpoints of the API. This provider is using django-oauth-toolkit.
Let's assume there is a registered client with "password" grant type, so that the end users only need to provide their credentials in the front-end in order to get an access token from the back-end.
At some point we want to add some support for social networks login and we decide to use python-social-auth (PSA) to that end. Here is the workflow I want to achieve:
The user logs in on Facebook from the front-end (via the Facebook SDK) and we get an access token back from the OAuth2 provider of Facebook.
We send the Facebook token to an endpoint of our REST API. This endpoint uses the Facebook token and django-social-auth to authenticate the user in our Django application (basically matching a Facebook account to a standard account within the app).
If the authentication succeeds, the API endpoint requests an access token from the OAuth2 provider for this newly authenticated user.
The Django access token is sent back to the front-end and can be used to access the REST API in exactly the same way that a regular user (i.e. logged in with his credentials) would do.
Now my problem is: how do I achieve step 3? I first thought I would register a separate OAuth2 client with Client Credentials Grant but then the generated token is not user-specific so it does not make sense. Another option is to use the TokenAuthentication from DRF but that would add too much complexity to my project. I already have an OAuth server and I don't want to set up a second token provider to circumvent my problem, unless this is the only solution.
I think my understanding of PSA and django-oauth-toolkit is not deep enough to find the best way of reaching my goal, but there must be a way. Help!
I managed to get something working using urllib2. I can't speak towards whether or not this is good practice, but I can successfully generate an OAuth2 token within a view.
Normally when I'd generate an access token with cURL, it'd look like this:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/
So we're tasked with making urllib2 accomplish this. After playing around for some bit, it is fairly straightforward.
import urllib, urlib2, base64, json
# Housekeeping
token_url = 'http://localhost:8000/auth/token/'
data = urllib.urlencode({'grant_type':'password', 'username':<username>, 'password':<password>})
authentication = base64.b64encode('%s:%s' % (<client_id>, <client_secret>))
# Down to Business
request = urllib2.Request(token_url, data)
request.add_header("Authorization", "Basic %s" % authentication)
access_credentials = urllib2.urlopen(request)
json_credentials = json.load(access_credentials)
I reiterate, I do not know if this is in bad practice and I have not looked into whether or not this causes any issues with Django. AFAIK this will do this trick (as it did for me).
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.
Could someone show some example about using dropbox api with django?
Dropbox api is installed, readme is done, tests are done, how to go further?
Yes, you need to understand, how oauth works.
Consider the use-case, when you are trying to store uploaded files directly on user's dropbox account.
First of all, you have to register a developer account on dropbox site.
In your django views, a typical workflow is this:
ask dropbox for a request token, (it
notifies them that you will use
their api soon)
dba = auth.Authenticator(app_settings.CONFIG)
request_token = dba.obtain_request_token()
it's in the api's documentation how to
set up the config file
than you build an authentication url:
authorize_url = dba.build_authorize_url(request_token, callback='http://...'
the user sign in at dropbox.com, than
redirected back to your site
you should store now the request
token, but it's only useful to get the
access token!
you use the request token to get an
access token, it's now unique to the
user.
access_token = dba.obtain_access_token(request_token, 'verifier')
leave the verifier blank, it's preserved do future usage!
store the access token, you need it in any further operation(per session)
here you are! you should instantiate a client, it's defined
in the python-specific dropbox
package
drpbx_client = client.DropboxClient('server','content_server','port',dba,access_token)
the client is a helper object for file operations:
drpbx_client.put_file('dropbox', '/porn/', request.FILES['file'])
You must use the Dropbox REST api:
http://www.dropbox.com/developers/docs#api-specification
It uses oauth for authentication. Detailed guide and walkthrough can be found here:
http://hueniverse.com/oauth/