Consider this example for authentication from PHP at https://developers.soundcloud.com/docs/api/guide#authentication seem to suggest you can pass a redirect url as a parameter when you flow a user throught the authentication process:
require_once 'Services/Soundcloud.php';
// create client object with app credentials
$client = new Services_Soundcloud(
'CLIENT_ID', 'CLIENT_SECRET', 'REDIRECT_URL');
// redirect user to authorize URL
header("Location: " . $client->getAuthorizeUrl());
Note the 'REDIRECT_URL' argument in the call to the constructor.
That seems to suggest I can pass an arbitrary redirect url as a parameter, just like you can do with Twitter (the API is quite similar).
However, if I pass an url that does not match the unique redirect url configured for the application, I get an error when the user is redirected to my url:
error=redirect_uri_mismatch&error_description=The+redirection+URI+provided+does+not+match+a+pre-registered+value.
So, what is that parameter supposed to be for, if the only valid value is the redirect url configured for the application?
And how are you supposed to handle authentication if the user can only be redirected to a single fixed url after authentication?? That makes the API completely unusable. When you have a user login into any API (e.g. Twitter or Facebook), you need them to be returned to the page from which they clicked the link to log in, and it is a ridiculous restriction that that url be unique. No other social network api that I've ever seen has this restriction.
Is SoundCloud API really so flawed or am I missing something?
I got an answer from Glen Scott, the author of the php-soundcloud library (a pretty decent wrapper around this terrible API) who provides a workaround. It's painful as it involves an additional redirect but it's all the API allows.
https://github.com/mptre/php-soundcloud/issues/36
I quote:
The API does not allow an arbitrary URL. As you noted, this is unlike
most other oAuth-backed social network API's. The workaround I can
recommend is using the state parameter to pass back your return URL.
You can do this when generating the authorization URL like this:
$client->getAuthorizeUrl(
array(
'state' => 'http://example.com/return'
) You'll get the state parameter added to the static redirect URL. For example, if you set your redirect URL to
http://example.com/callback then SoundCloud will redirect an
authenticated user to
http://example.com/callback?state=http://example.com/return
Your callback script will need to look for the state GET parameter,
and redirect using it.
Related
There are many other question related to this, but they didn't help me fix my problem.
I'm using the Facebook server-side login for a website, which I want to test locally. The path that initiates the login action is [http://localhost:8080/fblogin] (this redirects to the Facebook login dialogue, and goes from there).
I can successfully get the code, but when I try to exchange that for an access token, I get the following error:
{"error":{"message":"Missing redirect_uri parameter.","type":"OAuthException","code":191}}
I am providing the redirect_uri, url encoded and it is the same as the one I use to get the first code. Here is the url I'm using to request the access token (with the all-caps query string parameters replaced with their actual values, of course):
https://graph.facebook.com/oauth/access_token?client_id=CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Ffblogin&client_secret=CLIENT_SECRET&code=CODE_FROM_FB
I suspect this might have to do with how my app is set up on Facebook. Here are the values I have set:
Display Name: (an actual display name here)
App Domains: localhost
Contact email: (an actual email here)
Site URL: [http://localhost:8080/fblogin]
What do I need to tweak in the settings to get this to work? Or does this look correct?
By the way, if it makes any difference, I am using the Play! framework, version 2.0.1
After digging around a little more, I found that it was necessary for me to use POST when sending the request from my server to get the access token.
Interesting that using POST worked for you as this didn't for me.
In any case, did you add the query parameters using setQueryParameter()? (see How to make multiple http requests in play 2?)
I'm using FB.login on the JS client and want to verify the user's identity on the server. So, the client gets a signedRequest from facebook and sends it to the server. The server splits on the period, and decodes the second part of the signedRequest into a json object.
What should I be using for "code" when I send my server-side request to
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&redirect_uri=YOUR_REDIRECT_URI
&client_secret=YOUR_APP_SECRET
&code=CODE_GENERATED_BY_FACEBOOK
My decoded json looks something like:
{"algorithm":"HMAC-SHA256","code":"2.AQCPA_yfx4JHpufjP.3600.1335646800.1-5702286|l11asGeDQTMo3MrMx3SC0PksALj6g","issued_at":1335642445,"user_id":"5232286"}
Is that the code I need? Does it need to be B64 encoded? If this isn't the code, what code should I use?
_
What I've tried:
The request I'm trying to use is:
https://graph.facebook.com/oauth/access_token?client_id=295410083869479&redirect_uri=https://squaredme.appspot.com/facebookredirect&client_secret=44f1TOPSECRETbb8e&code=2.AQCPA_yfx4JHpufjP.3600.1335646800.1-5702286|l11asGeDQTMo3MrMx3SC0PksALj6g
but this returns the error:
{"error":{"message":"Error validating verification code.","type":"OAuthException","code":100}}
I can't tell if this is because I'm using a bad code, or what. Noteably, this is running on my local dev server, and squaredme.appspot.com definitely does NOT resolve to my IP. I don't know if facebook checks that or what - I'm assuming I'd get a better error message. Thanks for any direction!
You are trying to somehow combine the two flows together and that's why things don't work well.
When facebook POSTs into the iframe with your app url and a signed request there are two options, the easy one being that the user is already authenticated and then the signed request will have all the necessary data (including a signed request), then you just load the canvas page and use the JS SDK to get an access token there as well, but in this case there's no need to use the FB.login (since it opens a popup and will automatically close it), you can use the FB.getLoginStatus method which won't annoy the user.
If the user is not authenticated then the sign request will be missing the things you need to use the graph api.
You then redirect the user to the auth dialog, and since you are loaded in an iframe you'll need to return a html response which redirects the parent window using javascript, like:
top.location.href = "AUTH_DIALOG_URL";
When the use is done (accepted or rejected the app) he will be redirected to the "redirect_uri" you added as a parameter to the auth dialog.
If the user accepted your app then you'll be getting the "code" parameter in the query string.
You then take the code, exchange it with an access token as you posted in your question, and then redirect the user back to "apps.facebook.com/YOUR_APP".
When the page then loads the user is already authenticated and you'll be getting a full signed request.
I hope this clarifies things for you, recheck the Server-Side flow it pretty much covers it all.
I also had some trouble with that, then I found the solution here in StackOverflow.
There are two kinds of "code" provided by facebook. One comes inside the signedRequest in the cookie generated by the client-side flow. The Facebook's JS SDK handles this codes and get a access token without telling us anything.
The other type of code comes attached as a query to your redirect URI (http://www.yoururl.com/index.php?code=AAAgyiaus...), when you navigate to OAuth URL (server-side flow). With this code, you go to a Token URL and get your access token.
When you are using the server-side flow, you need to indicate a redirect URI both in the OAuth URL AND in the Token URL, and they have to be exactly the same, so a missing slash or a query string can be a lot of problem.
The codes are different from each other. When you use the both things together, appears to be impossible to get a access token using the code that was inside the cookie's signedRequest.
BUT, it is not. The magic is: the code from signedRequest is associated with NO URI, so as long as the redirect_uri is a mandatory field, all you have to do is to pass it blank when you navigate to the Token URL.
So the final solution is: grab the signedRequest from the cookie, parse it in your server to obtain the code, then read the Token URL:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&redirect_uri=&client_secret=YOUR_APP_SECRET
&code=CODE_INSIDE_THE_SIGNED_REQUEST
It looks like a hack, so I don't know how long it's gonna work, but it's working right now.
I have a website in which i use the Facebook API to let users 'invite' their friends to my site. These friends will get an App invite on their Facebook and once they click and accept it, it opens a page of my site in side an iFrame (within Facebook).
That's all fine, but i would like to add a refer id to the URL. So i can tell from who they got the invitation.
Is it possible to add (dynamic) parameters to the canvas URL??
I haven't been able to find out how to do this.
(I'm using the JS library).
I am able to pass multiple params to my canvas page. Not quite sure why this is not working for you or for #JonCanning. I am able to successfully redirect to https://apps.facebook.com/MY-APP?param1=x¶m2=y¶m3=z and retrieve them within the code loaded in the iframe.
You cannot manipulate request urls if you use apprequests for invites though, so not sure how you plan to manipulate the request url. Is this a wall post mechanism?
But, if you are using apprequests for invites - you can pass an optional "data" param. This can be arbitrary JSON or a simple string. When a recipient clicks thru the invite, you will be provided a "request_id" param in the request redirector from Facebook. e.g. http:YOUR-INVITE-REDIRECT-URL?request_ids=REQUEST_ID. If multiple invites from the same app were sent to the user, you will get the request_ids as a comma separated list. You can make a call back to the facebook graph api endpoint for requests and get back all the info for the requests - including the "data" param you passed. This might work better for you since you have embedded all data in the request itself.
More info on dialogs here : https://developers.facebook.com/docs/reference/dialogs/requests/
A single parameter passed into your apps url is passed onto the iframe
http://apps.facebook.com/app_name/?param=hello
To add to #iyerrag's answer, to grab the data param from within your canvas handler, you have to call back into the facebook graph API. The call takes one of the request_ids passed in the http query and also an access token. I was able to use our app's access token (generated something like this Creating App Token).
The returned JSON document contains the value you passed in the data param in key 'data'.
Here's the gist, in Python:
requestIDStr = self.request.get('request_ids','')
requestIDs = requestIDStr.split(',')
requestID = requestIDs[0]
if requestID:
url = """https://graph.facebook.com/{}?access_token={}""".format(requestID, fbAccessToken)
try:
response = urllib2.urlopen(url)
responseDoc = response.read()
jsonResponse = json.loads(responseDoc)
dataParam = jsonResponse['data']
except Exception as e: logging.warning('unable to retrieve data param: {}'.format(e) )
i'm using facebook application using Facebook sharp. When i send permission request to facebook, Facebook send to me this url
mywebsite.com/facebook/gettoken#access_token=CODE&Expired_in=1232
public ActionResult gettoken(string access_token){
...
}
access_token return null
I'm checking Request.Url. but don't have any access_token parameter
How to get access_token in asp.net mvc?
In your redirect_uri you have a #. Take it out.
A # is a client side tag to say everything after this is for client browsers only and is never passed to the server, hence you never receive the access_token.
Additional Note
You can see the hash in Javascript as it is client side. Incase you decide to use the JS Facebook SDK.
Change the # in a ?. The first parameter should be an ?
Is there a way to go to a url without redirecting to it? Basically I want to call a url from within my application in the background so it can logout a reliant party.
Appreciate the help.
What you are trying to do does not compete us to answer as it's directly related to your own Authentication implementation.
A normal ASP.NET Authentication based in Forms Authentication you will need always to lunch the url from a browser as it is there that relies the Authentication given.
You can give yourself a try by opening your website and log in into it, after that, open other browser brand (not browser window) into your application url... you will see that you also need to login again as the Authentication is hook up into the first browser.
It's Up to you as Application Architect to make this by implementing another way of authentication, normally in this kind'a cases, this happend when consuming web services where you need a authentication code first (given by calling a Login method) and that code is always needed to be appended to the body or header of any call to the system.
This way you can easily remove the authentication code and all procedure calls will fail.
As said, this is not up to us, it's up to you to create the correct Authentication Layer.
from your comment
it's as simple as using WebClient object
WebClient client = new WebClient ();
string reply = client.DownloadString (address);
If you wish to transfer to a new url request you can still use
Server.TransferRequest()
The problem with this is that by not using a redirect the browsers address bar will not reflect the fact that you have moved their request to another URL.
To have the client visit a given URL in the background you should either make an AJAX call to it or possibly have an image with an src of your logout url (though you'd have to make sure that you return a FileResult of your image too). This is how most analytics packages call to their relevant urls in the background.
The problem here though is that neither is 100% reliable, turn off javascript or images on your browser and these results fail.
From what you've said I think what you're after is for a user to continue to any of a variety of pages rather than a specific logout page. If this is indeed the case your best solution is in fact a double redirect.
Have your application redirect to your logout url but before hand put the url of the page you want them to go to into tempdata. Then in the actionresult for the logout page you can do your logging out as required and return a redirect to the url from tempdata.