/// <summary> /// Returns the url to check the login status of Facebook. /// </summary> /// <param name="parameters"></param> /// <returns></returns> public static string GenerateFacebookLoginStatusUrl(IDictionary <string, string> parameters) { // todo: make these static somewhere else... (maybe setup defaults somewhere too) List <string> allowedParams = new List <string>(); allowedParams.Add("api_key"); allowedParams.Add("ok_session"); allowedParams.Add("no_session"); allowedParams.Add("no_user"); allowedParams.Add("session_version"); // typically '3' StringBuilder statusUrl = new StringBuilder(); statusUrl.Append("http://www.facebook.com/extern/login_status.php?"); List <string> paramList = new List <string>(); // todo: encode parameter values foreach (KeyValuePair <string, string> p in parameters) { if (allowedParams.Contains(p.Key)) { paramList.Add(p.Key + "=" + FacebookUtils.UrlEncode(p.Value)); } } statusUrl.Append(String.Join("&", paramList.ToArray())); return(statusUrl.ToString()); }
/// <summary> /// Make a request to the Facebook Graph API with the given string parameters. /// </summary> /// <param name="graphPath">Path to the resource in the Facebook graph.</param> /// <param name="parameters">key-value string parameters.</param> /// <param name="addAccessToken">Add whether to set the access token or not.</param> /// <returns>JSON string represnetation of the response.</returns> /// <remarks> /// See http://developers.facebook.com/docs/api /// /// Note that this method is synchronous. /// This method blocks waiting for a network reponse, /// so do not call it in a UI thread. /// /// To fetch data about the currently logged authenticated user, /// provide "/me", which will fetch http://graph.facebook.com/me /// /// For parameters: /// key-value string parameters, e.g. the path "search" with /// parameters "q" : "facebook" would produce a query for the /// following graph resource: /// https://graph.facebook.com/search?q=facebook /// </remarks> public T Get <T>(string graphPath, IDictionary <string, string> parameters, bool addAccessToken) where T : new() { var result = Get(graphPath, parameters, addAccessToken); return(FacebookUtils.DeserializeObject <T>(result)); }
/// <summary> /// Returns the url to logout of Facebook. /// </summary> /// <param name="parameters"></param> /// <returns></returns> public static string GenerateFacebookLogoutUrl(IDictionary <string, string> parameters) { // todo: make these static somewhere else... (maybe setup defaults somewhere too) List <string> allowedParams = new List <string>(); allowedParams.Add("next"); allowedParams.Add("access_token"); StringBuilder logoutUrl = new StringBuilder(); logoutUrl.Append("http://www.facebook.com/logout.php?"); List <string> paramList = new List <string>(); // todo: encode parameter values foreach (KeyValuePair <string, string> p in parameters) { if (allowedParams.Contains(p.Key)) { paramList.Add(p.Key + "=" + FacebookUtils.UrlEncode(p.Value)); } } logoutUrl.Append(String.Join("&", paramList.ToArray())); return(logoutUrl.ToString()); }
/// <summary> /// Publish to the Facebook Graph API. /// </summary> /// <param name="graphPath">Path to the resource in the Facebook graph.</param> /// <param name="parameters">key-value string parameters.</param> /// <returns>JSON string represnetation of the response.</returns> /// <remarks> /// See http://developers.facebook.com/docs/api /// /// Note that this method is synchronous. /// This method blocks waiting for a network reponse, /// so do not call it in a UI thread. /// /// To post to the wall of the currently logged authenticated user, /// provide "/me/feed", which will make a request to /// http://graph.facebook.com/me/feed /// /// For parameters: /// key-value string parameters, e.g. /// parameters "message" : "this is a message" would produce the /// follwing parameters /// message=this is a message /// </remarks> public T Post <T>(string graphPath, IDictionary <string, string> parameters) where T : new() { var response = Post(graphPath, parameters); return(FacebookUtils.DeserializeObject <T>(response)); }
/// <summary> /// Make a request to the Facebook Graph API to delete a graph object. /// </summary> /// <param name="graphPath">Path to the resource in the Facebook graph.</param> /// <returns>Returns result.</returns> /// <remarks> /// See http://developers.facebook.com/docs/api /// /// Note that this method is synchronous. /// This method blocks waiting for a network reponse, /// so do not call it in a UI thread. /// /// To delete objects in the graph, /// provide "/id", which will delete http://graph.facebook.com/id /// /// You can delete a like by providing /POST_ID/likes (since likes don't have an ID). /// </remarks> public T Delete <T>(string graphPath) where T : new() { var response = Delete(graphPath); return(FacebookUtils.DeserializeObject <T>(response)); }
} // fb_sig_country protected FacebookPostCallback(IDictionary <string, string> vars) { ApiKey = vars["fb_sig_api_key"]; AppId = vars["fb_sig_app_id"]; RequestedAt = vars["fb_sig_time"]; UserId = vars["fb_sig_user"]; LinkedAccountIds = (List <string>)FacebookUtils.FromJson(vars["fb_sig_linked_account_id"])["array"]; UsingNewFacebook = Convert.ToBoolean(vars["fb_sig_in_new_facebook"]); Country = vars["fb_sig_country"]; }
public static string ExchangeAccessTokenForCode(string code, string applicationKey, string applicationSecret, string postAuthorizeUrl, string userAgent, out long expiresIn) { if (string.IsNullOrEmpty(applicationKey)) { throw new ArgumentNullException("applicationKey"); } if (string.IsNullOrEmpty(applicationSecret)) { throw new ArgumentNullException("applicationSecret"); } if (string.IsNullOrEmpty(postAuthorizeUrl)) { throw new FacebookSharpException("postAuthorizeUrl"); } var client = new RestClient(GraphBaseUrl); var request = new RestRequest(Method.GET) { Resource = "oauth/access_token" }; request.AddParameter("client_id", applicationKey); request.AddParameter("redirect_uri", postAuthorizeUrl); request.AddParameter("client_secret", applicationSecret); request.AddParameter("code", code); var response = client.Execute(request); if (response.ResponseStatus == ResponseStatus.Completed) { // facebook gave us some result. string result = response.Content; // but mite had been an error var fbException = (FacebookException)result; if (fbException != null) { throw fbException; } // the result comes like the querystring // this allows us to make use of ParseUrlQueryString(string query) method. var pars = FacebookUtils.ParseUrlQueryString(result); expiresIn = pars.ContainsKey("expires_in") ? Convert.ToInt64(pars["expires_in"][0]) : 0; return(pars["access_token"][0]); } throw new FacebookRequestException(response); }
/// <summary> /// Validates facebook signed_request using the applicationSecret. /// </summary> /// <param name="signedRequest"> /// The signed request. /// </param> /// <param name="applicationSecret"> /// The application secret. /// </param> /// <param name="jsonObject"> /// The json object if validation passes, else null. /// </param> /// <returns> /// Returns true if validation passes, else false. /// </returns> public static bool ValidateSignedRequest(string signedRequest, string applicationSecret, out IDictionary <string, object> jsonObject) { if (signedRequest.StartsWith("signed_request=")) { signedRequest = signedRequest.Substring(15); } if (string.IsNullOrEmpty(applicationSecret)) { throw new ArgumentNullException("applicationSecret"); } jsonObject = null; string expectedSignature = signedRequest.Substring(0, signedRequest.IndexOf('.')); string payload = signedRequest.Substring(signedRequest.IndexOf('.') + 1); // Back & Forth with Signature // byte[] actualSignature = FromUrlBase64String(expectedSignature); // string testSignature = ToUrlBase64String(actualSignature); // Back & Forth With Data byte[] actualPayload = FromUrlBase64String(payload); string json = (new UTF8Encoding()).GetString(actualPayload); // string testPayload = ToUrlBase64String(actualPayload); // Attempt to get same hash var hmac = SignWithHmac( Encoding.UTF8.GetBytes(payload), Encoding.UTF8.GetBytes(applicationSecret)); var hmacBase64 = ToUrlBase64String(hmac); if (hmacBase64 != expectedSignature) { return(false); } jsonObject = FacebookUtils.FromJson(json); return(true); }
/// <summary> /// Parse incoming POST request /// </summary> /// <param name="post_data"> /// The raw post data from Request.Form /// </param> /// <param name="applicationSecret"> /// The application secret. /// </param> /// <returns> /// Returns a FacebookPostCallback object if validation passes, else null. /// </returns> public static FacebookPostCallback Parse(string post_data, string applicationSecret) { var post_vars = FacebookUtils.ParseUrlQueryString(post_data); IDictionary <string, string> post_variables = new Dictionary <string, string>(); foreach (var p in post_vars) { post_variables.Add(p.Key, p.Value[0].ToString()); } if (ValidateSignature(post_variables, applicationSecret)) { if (post_variables.ContainsKey("fb_sig_authorize")) { return(new PostAuthorizeCallback(post_variables)); } else if (post_variables.ContainsKey("fb_sig_uninstall")) { return(new PostRemoveCallback(post_variables)); } } return(null); }
/// <summary> /// Returns the url to login with Facebook. /// </summary> /// <param name="parameters"></param> /// <param name="extendedPermissions"></param> /// <returns></returns> public static string GenerateFacebookLoginUrl(IDictionary <string, string> parameters, string[] extendedPermissions) { // todo: make these static somewhere else... (maybe setup defaults somewhere too) List <string> allowedParams = new List <string>(); allowedParams.Add("api_key"); allowedParams.Add("next"); allowedParams.Add("canvas"); allowedParams.Add("display"); allowedParams.Add("cancel_url"); allowedParams.Add("fbconnect"); allowedParams.Add("return_session"); allowedParams.Add("session_version"); allowedParams.Add("v"); StringBuilder loginUrl = new StringBuilder(); loginUrl.Append("http://www.facebook.com/login.php?"); List <string> paramList = new List <string>(); // todo: encode parameter values foreach (KeyValuePair <string, string> p in parameters) { if (allowedParams.Contains(p.Key)) { paramList.Add(p.Key + "=" + FacebookUtils.UrlEncode(p.Value)); } } if (extendedPermissions != null && extendedPermissions.Length > 0) { paramList.Add("req_perms=" + String.Join(",", extendedPermissions)); } loginUrl.Append(String.Join("&", paramList.ToArray())); return(loginUrl.ToString()); }
public static FacebookAuthenticationResult Parse(string url, FacebookSettings facebookSettings) { IDictionary <string, string> paramters; if (url.StartsWith("http://www.facebook.com/connect/login_success.html")) { Uri uri = new Uri(url); if (!string.IsNullOrEmpty(uri.Fragment)) { var pars = FacebookUtils.ParseUrlQueryString(uri.Fragment); paramters = new Dictionary <string, string>(); foreach (var p in pars) { if (p.Key.StartsWith("#")) { paramters.Add(p.Key.Substring(1), p.Value[0]); } else { paramters.Add(p.Key, p.Value[0]); } } } else { var pars = FacebookUtils.ParseUrlQueryString(url); paramters = new Dictionary <string, string>(); foreach (var p in pars) { paramters.Add(p.Key, p.Value[0]); } } return(new FacebookAuthenticationResult(paramters)); } // for now don't allow to parse silverlight and windows phone web, // coz ExchangeAccessTokenForCode needs to have async version. #if !(SILVERLIGHT || WINDOWS_PHONE) else { // its from web var uri = new Uri(url); var pars = FacebookUtils.ParseUrlQueryString(uri.Query); paramters = new Dictionary <string, string>(); foreach (var p in pars) { paramters.Add(p.Key, p.Value[0]); } if (paramters.ContainsKey("signed_request")) { // if we are accessing from iframe canvas // note: needs to enable Canvas Session Parameter and OAuth 2.0 for Canvas (beta) in Migration Tab in app settings. // might add other features later on. if (facebookSettings == null) { throw new ArgumentNullException("facebookSettings"); } if (string.IsNullOrEmpty(facebookSettings.ApplicationSecret)) { throw new ArgumentNullException("facebookSettings.ApplicationSecret"); } IDictionary <string, object> jsonObject; if (!ValidateSignedRequest(paramters["signed_request"], facebookSettings.ApplicationSecret, out jsonObject)) { throw new InvalidSignedRequestException(); } return(new FacebookAuthenticationResult(jsonObject)); } else if (paramters.ContainsKey("code")) { // incase this is from the web, we need to exchange the code with access token if (facebookSettings == null) { throw new ArgumentNullException("facebookSettings"); } long expiresIn; string accessToken = Facebook.ExchangeAccessTokenForCode(paramters["code"], facebookSettings.ApplicationKey, facebookSettings.ApplicationSecret, facebookSettings.PostAuthorizeUrl, facebookSettings.UserAgent, out expiresIn); return(new FacebookAuthenticationResult(accessToken, expiresIn, null)); } } #endif // if its parse error return(new FacebookAuthenticationResult(string.Empty, 0, string.Empty)); }
public T GetResponseAs <T>() { return(FacebookUtils.DeserializeObject <T>(RawResponse)); }