skip to Main Content

Well, I am a new guy who is trying to develop a web application whose user are will be authenticated through Facebook. I am developing the application in MVC 4 .Net Framework. As it’s internal programs are already done so I need not to do much coding. I have just put the API ID and Secret Key in the scope

OAuthWebSecurity.RegisterFacebookClient(
                appId: "750397051803327",
                appSecret: "**************************");

And here is my Application http://imgur.com/a/k4Vd0
My Application is taking properly the user permission from the user perfectly. http://imgur.com/a/bqzj5 but after taking permission it is not providing the login state of the user by showing such exception http://imgur.com/a/h81Oh login failed. I debugged form the code end and I observed that it is sending isLoggedin as false http://imgur.com/a/UuLIe therefore my I am not getting the access.

However 2 days before I am not getting such exception. I was getting data simply fine. Here is a snapshot of my previous data. http://imgur.com/a/Bc49F

I need that data again, but how? Is there anything need to change in my application dashboard? Possibly I have changed something in application dashboard. if yes then what is particularly that?
Another things I’m confused that what is the need for PRODUCTS? Do I need anything from the products for this special reason to get the data. If yes then which one shall I need and how to configure it to get back my previous systematic process in which I was getting data smoothly.

If I add App Center from the PRODUCTS I am obtaining two other secret keys like Account Kit App Secret and Account Kit Client Token Is that I need to use these keys for my requested case. For such login approval specific which Products are need or nothing need at all from PRODUCTS. I am so confused about it how to configure an application.

Please suggest me how to solve this problem in addition how to configure my application API. Thank you.

2

Answers


  1. Chosen as BEST ANSWER

    Yes!!!! I got the solution of my own problem. According to Facebook developers bug report all Facebook log is not working from 28th March 2017. They also let us know through their developers Facebook group. The post link is here.

    According to one of the Developer teams had said we're finding that facebook authentication just stopped working (2pm EST) across multiple apps that we manage. apps haven't changed, apps haven't been suspended..... not sure where to report this since "status" is all good......


  2. According to Previous Answer I got my solution. In MVC4 everyone write down their AppID and SecurityCode. Due to change of facebook GRAPH API those previous links are broken. Consequently everyone need to change the RegisterFacebookClient calss. But this class is a sealed class in the .Net library, so anyone can’t extend or overwrite it. As a result we need to use a wrapper class. Let us consider my Wrapper class is FacebookClientV2Dot3 therefore my class will be

    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Web;
    using DotNetOpenAuth.AspNet.Clients;
    using Newtonsoft.Json;
    
    public class FacebookClientV2Dot3 : OAuth2Client
    {
        #region Constants and Fields
    
        /// <summary>
        /// The authorization endpoint.
        /// </summary>
        private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth";
    
        /// <summary>
        /// The token endpoint.
        /// </summary>
        private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token";
    
        /// <summary>
        /// The user info endpoint.
        /// </summary>
        private const string UserInfoEndpoint = "https://graph.facebook.com/me";
    
        /// <summary>
        /// The app id.
        /// </summary>
        private readonly string _appId;
    
        /// <summary>
        /// The app secret.
        /// </summary>
        private readonly string _appSecret;
    
        /// <summary>
        /// The requested scopes.
        /// </summary>
        private readonly string[] _requestedScopes;
    
        #endregion
    
        /// <summary>
        /// Creates a new Facebook OAuth2 client, requesting the default "email" scope.
        /// </summary>
        /// <param name="appId">The Facebook App Id</param>
        /// <param name="appSecret">The Facebook App Secret</param>
        public FacebookClient(string appId, string appSecret)
            : this(appId, appSecret, new[] { "email" }) { }
    
        /// <summary>
        /// Creates a new Facebook OAuth2 client.
        /// </summary>
        /// <param name="appId">The Facebook App Id</param>
        /// <param name="appSecret">The Facebook App Secret</param>
        /// <param name="requestedScopes">One or more requested scopes, passed without the base URI.</param>
        public FacebookClient(string appId, string appSecret, params string[] requestedScopes)
            : base("facebook")
        {
            if (string.IsNullOrWhiteSpace(appId))
                throw new ArgumentNullException("appId");
    
            if (string.IsNullOrWhiteSpace(appSecret))
                throw new ArgumentNullException("appSecret");
    
            if (requestedScopes == null)
                throw new ArgumentNullException("requestedScopes");
    
            if (requestedScopes.Length == 0)
                throw new ArgumentException("One or more scopes must be requested.", "requestedScopes");
    
            _appId = appId;
            _appSecret = appSecret;
            _requestedScopes = requestedScopes;
        }
    
        protected override Uri GetServiceLoginUrl(Uri returnUrl)
        {
            var state = string.IsNullOrEmpty(returnUrl.Query) ? string.Empty : returnUrl.Query.Substring(1);
    
            return BuildUri(AuthorizationEndpoint, new NameValueCollection
                    {
                        { "client_id", _appId },
                        { "scope", string.Join(" ", _requestedScopes) },
                        { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) },
                        { "state", state },
                    });
        }
    
        protected override IDictionary<string, string> GetUserData(string accessToken)
        {
            var uri = BuildUri(UserInfoEndpoint, new NameValueCollection { { "access_token", accessToken } });
    
            var webRequest = (HttpWebRequest)WebRequest.Create(uri);
    
            using (var webResponse = webRequest.GetResponse())
            using (var stream = webResponse.GetResponseStream())
            {
                if (stream == null)
                    return null;
    
                using (var textReader = new StreamReader(stream))
                {
                    var json = textReader.ReadToEnd();
                    var extraData = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
                    var data = extraData.ToDictionary(x => x.Key, x => x.Value.ToString());
    
                    data.Add("picture", string.Format("https://graph.facebook.com/{0}/picture", data["id"]));
    
                    return data;
                }
            }
        }
    
        protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
        {
            var uri = BuildUri(TokenEndpoint, new NameValueCollection
                    {
                        { "code", authorizationCode },
                        { "client_id", _appId },
                        { "client_secret", _appSecret },
                        { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) },
                    });
    
            var webRequest = (HttpWebRequest)WebRequest.Create(uri);
            string accessToken = null;
            HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
    
            // handle response from FB 
            // this will not be a url with params like the first request to get the 'code'
            Encoding rEncoding = Encoding.GetEncoding(response.CharacterSet);
    
            using (StreamReader sr = new StreamReader(response.GetResponseStream(), rEncoding))
            {
                var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                var jsonObject = serializer.DeserializeObject(sr.ReadToEnd());
                var jConvert = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jsonObject));
    
                Dictionary<string, object> desirializedJsonObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(jConvert.ToString());
                accessToken = desirializedJsonObject["access_token"].ToString();
            }
            return accessToken;
        }
    
        private static Uri BuildUri(string baseUri, NameValueCollection queryParameters)
        {
            var keyValuePairs = queryParameters.AllKeys.Select(k => HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(queryParameters[k]));
            var qs = String.Join("&", keyValuePairs);
    
            var builder = new UriBuilder(baseUri) { Query = qs };
            return builder.Uri;
        }
    
        /// <summary>
        /// Facebook works best when return data be packed into a "state" parameter.
        /// This should be called before verifying the request, so that the url is rewritten to support this.
        /// </summary>
        public static void RewriteRequest()
        {
            var ctx = HttpContext.Current;
    
            var stateString = HttpUtility.UrlDecode(ctx.Request.QueryString["state"]);
            if (stateString == null || !stateString.Contains("__provider__=facebook"))
                return;
    
            var q = HttpUtility.ParseQueryString(stateString);
            q.Add(ctx.Request.QueryString);
            q.Remove("state");
    
            ctx.RewritePath(ctx.Request.Path + "?" + q);
        }
    }
    

    Look here you I have replaces all the API links by newer version links.

    Now you need to modify your

    AuthConfig

    Just use a wrapper class

    OAuthWebSecurity.RegisterClient(new FacebookClientV2Dot3("AppID", "HassedPassword"));
    

    Then all success. You facebook login will be back in previous state.

    However you can face a new issue regarding this new API rather than previous API, the problem is that IP Whitelisting. Like this image. Hope you will need nothing but this. Happy coding.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search