Search code examples
c#facebookfacebook-graph-apihttpwebrequesthttpwebresponse

Facebook Access Token - Automate Getting the Token


Go below to see answer

I am getting the Facebook access token fine, but where I am having troubles is when I am trying to automate this process.

If I visit this URL is the browser I get the access token just fine.

Example:

I paste this into the browser and hit return.

https://www.facebook.com/dialog/oauth?client_id=324234343434&scope=['ads_read', 'ads_management']&redirect_uri=http://www.kb-demos.com/login_success.html&response_type=token

Then I get sent to this page:

http://www.kb-demos.com/login_success.html?#access_token=34543534534534KJ534LKJLKJLKHLH4534534J5KH345KJ3L4H53KJ5H3K4LJH34KH54K&expires_in=5180653

I changed the access token piece so its not a real token

Viola access token!

What I am trying to do is replicate that same behavior with code. I am getting close but not quite there.

I keep getting the user_denied error.

%3Ferror%3Daccess_denied%26error_code%3D200%26error_description%3DPermissions%2Berror%26error_reason%3Duser_denied%23_%3D_&display=page&locale=en_US&logger_id=786a3153-1d81-415c-8dca-f8fa8b0cd630

I am outputting all headers to the console. It is the location header I am concerned with**

I think it has to do with the 302 redirect?

ApplicationId = request.ClientId;
string permissions = "['ads_management', 'ads_read']";

var destinationURL = String.Format(
@"https://www.facebook.com/dialog/oauth?client_id={0}&scope={1}&redirect_uri=http://www.kb-demos.com/login_success.html&response_type=token",
ApplicationId,
permissions);

// Create a new 'HttpWebRequest' Object to the mentioned URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(destinationURL);
myHttpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";

myHttpWebRequest.AllowAutoRedirect = false;
// Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

//Console.WriteLine("\nThe HttpHeaders are \n\n\tName\t\tValue\n{0}", myHttpWebRequest.Headers); // my http headers
// Print the HTML contents of the page to the console. 


var headers = myHttpWebResponse.Headers;

// output all the headers
foreach(var header in headers) {
    Console.WriteLine(header.ToString() + ": " + headers[header.ToString()] + "\n" );

}

#region
//Stream streamResponse = myHttpWebResponse.GetResponseStream();
//StreamReader streamRead = new StreamReader(streamResponse);
//Char[] readBuff = new Char[256];
//int count = streamRead.Read(readBuff, 0, 256);
//Console.WriteLine("\nThe HTML contents of page the are  : \n\n ");
//while (count > 0)
//{
//    String outputData = new String(readBuff, 0, count);
//    Console.Write(outputData);
//    count = streamRead.Read(readBuff, 0, 256);
//}
//// Close the Stream object.
//streamResponse.Close();
//streamRead.Close();
// Release the HttpWebResponse Resource.
#endregion


myHttpWebResponse.Close();

Console.ReadLine();

I am getting a user_denied error here. But in the browser I am getting a perfectly good token. I cannot figure out why.

enter image description here

The headers in the location header it seems to work when using the browser.

Possible scenario if I cannot get the above to work: I was wondering if there is a browser with an API? Something I can call from the command line - pass in some arguments - and then get the redirect url is a variable to parse?


Solution

  • This code will automate the retrieval of the access_token. You must have credentials to the account you are requesting an access token for.

    Updated

    First login to the facebook account.

            // LOG INTO FACEBOOK ACCT
            string email = "youremail@blah.com";
            string pw = "yourPassWord";
    
            CookieContainer cookieJar = new CookieContainer();
    
            HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("https://www.facebook.com");
            request1.CookieContainer = cookieJar;
    
            request1.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
    
            //Get the response from the server and save the cookies from the first request..
            HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
            var cookies = response.Cookies;
            cookieJar.Add(cookies);
            response.Close();// close the response
    
    
            string getUrl = "https://www.facebook.com/login.php?login_attempt=1";
    
            string postData = String.Format("email={0}&pass={1}", email, pw);
            HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
            getRequest.CookieContainer = cookieJar;
            //Adding Previously Received Cookies 
            getRequest.CookieContainer.Add(cookies);
            getRequest.Method = WebRequestMethods.Http.Post;
            getRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
            getRequest.AllowWriteStreamBuffering = true;
            getRequest.ProtocolVersion = HttpVersion.Version11;
            getRequest.AllowAutoRedirect = true;
            getRequest.ContentType = "application/x-www-form-urlencoded";
    
            byte[] byteArray = Encoding.ASCII.GetBytes(postData);
            getRequest.ContentLength = byteArray.Length;
            Stream newStream = getRequest.GetRequestStream(); //open connection
            newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
            newStream.Close();
    
            HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
            using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
            {
                string sourceCode = sr.ReadToEnd();
            } 
    

    Then request the access_token

                    ApplicationId = request.ClientId; // your application id
                    string permissions = "['ads_management', 'ads_read']";
    
                    var destinationURL = String.Format(
                    @"https://www.facebook.com/dialog/oauth?client_id={0}&scope={1}&redirect_uri=http://www.kb-demos.com/login_success.html&response_type=token",
                    ApplicationId,
                    permissions);
    
                    // Create a new 'HttpWebRequest' Object to the mentioned URL.
                    HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(destinationURL);
                    // use the same cookie container and cookies
                    myHttpWebRequest.CookieContainer = cookieJar;
                    myHttpWebRequest.CookieContainer.Add(cookies); //recover cookies First request
    
                    myHttpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
    
                    myHttpWebRequest.AllowAutoRedirect = false;
                    // Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable.
                    HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
    
                    Console.WriteLine("\nThe Request HttpHeaders are \n\n\tName\t\tValue\n{0}", myHttpWebRequest.Headers); // my http headers
                    Console.WriteLine("\nThe Request HttpHeaders are \n\n\tName\t\tValue\n{0}", myHttpWebRequest.CookieContainer); // my http headers
                    //Console.WriteLine("\nThe Request HttpHeaders are \n\n\tName\t\tValue\n{0}", cookies); // my http headers
    
                    var headers = myHttpWebResponse.Headers;
                    // output all the headers
                    foreach (var header in headers)
                    {
                        Console.WriteLine(header.ToString() + ": " + headers[header.ToString()] + "\n");
    
                    }
    
                    var cow = GetParams(headers["Location"]);
                    string accessToken = "";
                    accessToken = cow["#access_token"];
    

    And the helper method

        /// <summary>
        /// Helper method to get Params from URL using RegEx
        /// </summary>
        static Dictionary<string, string> GetParams(string uri)
        {
            var matches = Regex.Matches(uri, @"[\?&](([^&=]+)=([^&=#]*))", RegexOptions.Compiled);
            return matches.Cast<Match>().ToDictionary(
                m => Uri.UnescapeDataString(m.Groups[2].Value),
                m => Uri.UnescapeDataString(m.Groups[3].Value)
            );
        }