FacebookRedirect.axd not preserving querystring?
Im using the fb sdk iframe canvas 4.2.1 lastest version and have come acrosss a problem with when the user first comes to my site via a url that they can click on via their friends wall:
http://apps.facebook.com/<mysite>/Video/View/23?ItemID=8
I grant the application basic permissions but the return url looks like this:
http://apps.facebook.com/<mysite>/Video/View/23
It's completely chopped off the ItemID???
Is this a bug in the SDK? If so, how do I fix it?
I have my route setup as:
routes.MapRoute(
"ViewItem",
"{controller}/{action}/{ItemID}/{TR}",
new { controller = "Video", action = "View", TR = UrlParameter.Optional }
);
The beginning of my controller action looks like this:
[HttpPost]
[CanvasAuthorize]
public ActionResult View(long ItemID, long? TR)
{
...
Note: The url is being generated through standard means, so please don't tell me my querystring is wrong. I'm using Url.CanvasAction to generate the url, so everything is hunky dory up until that point when the user clicks and gets redirected to authenticate the app then it returns with a effed-up querystring.
I've tried stepping through the code to see where i goes wrong but can't find it, the nearest I've come to is that the facebookredirect.axd file is the last thing to be called and somewhere inside that, its stuffing it all up!
Any help or advice would be appreciated
thanks ...
<< UPDATE >>
I've since written another action to check and get the required permissions for a particular process.
[HttpPost]
public ActionResult RequestPermission(string Permission, string ReturnUrl, long? TR)
{
FacebookApp app = new FacebookApp();
var authorizer =开发者_StackOverflow中文版 new CanvasAuthorizer(app);
if (Permission.Length > 0)
{
authorizer.Perms = Permission;
authorizer.ReturnUrlPath = Server.UrlDecode(ReturnUrl);
authorizer.Authorize();
}
return new EmptyResult();
}
I get a "potentially dangerous request path was detected" error message from asp.net.
The url in the address bar looks like this:
http://www.<myinternetsite>.com/facebookredirect.axd//<myfacebookapp>/http://apps.facebook.com/<myfacebookapp>/Video/View/108?perms=email&selected_profiles=55424639&session={%22session_key%22%3A%111.PfJ_2D8Q8a71orTjpzWGFQ__.3600.1295251200-763424639%22%2C%22uid%3A%22763424639%22%2C%22expires%22%3A1295251200%2C%22secret%22%3A%22Chi8iKzFqQg9zb8vdMPNag__%22%2C%22access_token%22%3A%22124828944240034|2.PfJ_2Dfdfdf1orTjpzPHFQ__.3600.4343451200-343424639|S4-dr00eU6GXUmoatU7QOWGGUVE%22%2C%22sig%22%3A%22322985031c75727b9fe31993dd2e3%22}
Note: I've intentionally changed some fo the above codes and chars to prevent my site being hacked.
One thing I can already notice in the above url is the return url:
http://apps.facebook.com/<myfacebookapp>/Video/View/108?perms=email...
what it should read is this:
http://apps.facebook.com/<myfacebookapp>/Video/View/108?ItemID=11&perms=email...
notice how my ItemID is being removed by the CanvasAuthorizer. This obviously is an error it shouldn't be doing that! Leave the fricken thing alone!
Perhaps the authorizer needs to url encode my returnUrl???
Any help here???
This is a limitation in the Facebook login system rather than the Facebook C# SDK. Facebook strips querystrings when doing the authorization. This will be fixed when we implement the new authentication system that uses the full oauth 2 spec.
I have no idea at what point the authors of the Facebook C# SDK decided that this is a limitation of Facebook itself. Just for the experiment I hacked CanvasUrlBuilder.BuildAuthReturnUrl() to include the query instead of stripping it away (the "uriBuilder.Query = null; // No Querystrings allowed in return urls" part).
Can you guess what happened? It worked! Apparently at some point the return URL gets URL encoded and Facebook happily passes along all query parameters.
So, yeah...
EDIT: Here's the patched method. Open Facebook.Web.CanvasUrlBuilder and replace BuildAuthReturnUrl with this one. Doing so will preserve all query parameters during FB login and/or app authorization. I'm not entirely sure but this implementation may break something related to canceling during the process, as it bypasses FacebookRedirect.axd entirely. YMMV as I've no more problems with the FB C# SDK so far.
private Uri BuildAuthReturnUrl(string pathAndQuery, bool cancel)
{
Contract.Ensures(Contract.Result<Uri>() != null);
if (!string.IsNullOrEmpty(pathAndQuery) && pathAndQuery.StartsWith("/", StringComparison.Ordinal))
{
pathAndQuery = pathAndQuery.Substring(1);
}
if (pathAndQuery == null)
{
pathAndQuery = CurrentCanvasPathAndQuery;
}
string path, query;
if (pathAndQuery.Contains('?'))
{
string[] strings = pathAndQuery.Split('?');
path = strings[0];
query = strings[1];
}
else
{
path = pathAndQuery;
query = null;
}
if (!path.StartsWith("/", StringComparison.Ordinal))
{
path = "/" + path;
}
var appPath = request.ApplicationPath;
if (appPath != "/")
{
appPath = string.Concat(appPath, "/");
}
string redirectRoot = string.Concat(redirectPath, "/", cancel ? "cancel" : string.Empty);
UriBuilder uriBuilder = new UriBuilder("http://apps.facebook.com");
//uriBuilder.Path = string.Concat(appPath, redirectRoot, CanvasPageApplicationPath, path);
uriBuilder.Path = string.Concat(CanvasPageApplicationPath, path);
uriBuilder.Query = query; // No Querystrings allowed in return urls
return uriBuilder.Uri;
}
精彩评论