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.
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?
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)
);
}
Related
I want to login to Rockstar Social Club page https://pl.socialclub.rockstargames.com
I have this script
public static void Login()
{
string firstUrl = "https://pl.socialclub.rockstargames.com/profile/signin";
string formParams = string.Format("login-field={0}&password-field={1}", "mynickname", "mypassword");
string cookieHeader;
WebRequest req = WebRequest.Create(firstUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
string pageSource;
string getUrl = "https://pl.socialclub.rockstargames.com/games/gtav/pc/career/overview/gtaonline";
WebRequest getRequest = WebRequest.Create(getUrl);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse(); //Here returns me this error: System.Net.WebException: 'An error occurred while sending the request"
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
}
Error occures in WebResponse getResponse = getRequest.GetResponse();
System.Net.WebException: 'An error occurred while sending the request'
I don't know how to repair this, and succesfully login to this website.
I have accomplished what you are attempting to do, but on a different website.
Basically - a few years ago, I wanted to create a website that would track my Guild/Company details on Final Fantasy XIV.
They didn't have an API, so I made one.
In order to get the information I required, I needed to use a mix of HtmlAgilityPack along with the C# WebBrowser control.
In order to pass the verification token stage above, you need to run the page source in a Web Browser control.
This will allow dynamic fields and data to be generated.
You then need to take that data, and submit it with your post data.
This is to fool it into thinking the request is coming from the page.
Be warned, when doing your posts - you may need to allow for redirects and you may need to mirror the referrer and host fields to match the website you are emulating.
The specific process I followed was:
Navigate to login page in WebBrowser control
Get page source
Load into HtmlAgilityPack HtmlDocument class
Use XPath to scrape the login form.
Take _verification tokens, csrf tokens etc make note of them.
Post a web-request with the necessary data to the form target destination url.
Read the response
Be aware - sometimes the response will actually be html code that tells it to do a Javascript redirect - in my case with Final Fantasy XIV - it was loading up another form and performing an autopost on page load.
You will also want to use
LoggedInCookies = new CookieContainer();
In your first HttpWebRequest
followed by:
request.CookieContainer = LoggedInCookies;
for each subsequent request.
The cookie container will trap and persist the authentication related cookies, while the WebBrowser control and HtmlAgilityPack will allow you to scrape the fields from the web forms that you need to break through.
Adding some code from wayback when I solved this for Final Fantasy XIV's lodestone website.
This code is very old and may not work anymore, but the process it follows could be adapted for sites that do not use Javascript as part of the login process.
Pay attention to the areas where it allows the request to be redirected, this is because the Server endpoint you are calling may do Action redirects etc
If your request does not allow those redirects, then it will not be emulating the login process.
class LoggedInClient
{
public static CookieContainer LoginCookie(string user, string pass)
{
string sStored = "";
string url = "http://eu.finalfantasyxiv.com/lodestone/account/login/";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
CookieContainer cookies = new CookieContainer();
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36";
request.CookieContainer = cookies;
HttpWebResponse response1 = (HttpWebResponse)request.GetResponse();
Console.WriteLine(cookies.Count.ToString());
string sPage = "";
using (var vPage = new StreamReader(response1.GetResponseStream()))
{
sPage = vPage.ReadToEnd();
}
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(sPage);
sStored = doc.DocumentNode.SelectSingleNode("//input[#type='hidden' and #name='_STORED_']").Attributes["value"].Value;
string param = "sqexid="+user+"8&password="+pass+"&_STORED_=" + sStored;
string postURL = doc.DocumentNode.SelectSingleNode("//form[#name='mainForm']").Attributes["action"].Value;
//Console.WriteLine(sStored);
postURL = "https://secure.square-enix.com/oauth/oa/" + postURL;
request.Method = "POST";
byte[] paramAsBytes = Encoding.Default.GetBytes(param);
request = (HttpWebRequest)WebRequest.Create(postURL);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36";
request.CookieContainer = cookies;
request.AllowAutoRedirect = false;
try
{
using (Stream stream = request.GetRequestStream())
{
stream.Write(paramAsBytes, 0, paramAsBytes.Length);
}
}
catch (Exception ee)
{
Console.WriteLine(ee.ToString());
}
string sGETPage = "";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var vPage = new StreamReader(response.GetResponseStream()))
{
sPage = vPage.ReadToEnd();
sGETPage = response.Headers["Location"];
}
}
// Console.WriteLine(sPage);
request = (HttpWebRequest)WebRequest.Create(sGETPage);
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36";
request.CookieContainer = cookies;
HttpWebResponse response2 = (HttpWebResponse)request.GetResponse();
Console.WriteLine(cookies.Count.ToString());
sPage = "";
using (var vPage = new StreamReader(response2.GetResponseStream()))
{
sPage = vPage.ReadToEnd();
}
// Console.WriteLine(sPage);
doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(sPage);
string _c = doc.DocumentNode.SelectSingleNode("//input[#type='hidden' and #name='_c']").Attributes["value"].Value;
string cis_sessid = doc.DocumentNode.SelectSingleNode("//input[#type='hidden' and #name='cis_sessid']").Attributes["value"].Value;
string action = doc.DocumentNode.SelectSingleNode("//form[#name='mainForm']").Attributes["action"].Value;
string sParams = "_c=" + _c + "&cis_sessid=" + cis_sessid;
byte[] bData = Encoding.Default.GetBytes(sParams);
// Console.WriteLine(sStored);
request = (HttpWebRequest)WebRequest.Create(action);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36";
request.CookieContainer = cookies;
request.AllowAutoRedirect = true;
try
{
using (Stream stream = request.GetRequestStream())
{
stream.Write(bData, 0, bData.Length);
}
}
catch (Exception ee)
{
Console.WriteLine(ee.ToString());
}
string nextPage = "";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var vPage = new StreamReader(response.GetResponseStream()))
{
nextPage = vPage.ReadToEnd();
}
}
// Console.WriteLine(nextPage);
doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(nextPage);
string csrf_token = doc.DocumentNode.SelectSingleNode("//input[#type='hidden' and #name='csrf_token']").Attributes["value"].Value;
string cicuid = "51624738";
string timestamp = Convert.ToInt32(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds).ToString() + "100";
action = "http://eu.finalfantasyxiv.com/lodestone/api/account/select_character/";
sParams = "csrf_token=" + csrf_token + "&cicuid=" + cicuid + "×tamp=" + timestamp;
bData = Encoding.Default.GetBytes(sParams);
request = (HttpWebRequest)WebRequest.Create(action);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36";
request.CookieContainer = cookies;
request.AllowAutoRedirect = true;
try
{
using (Stream stream = request.GetRequestStream())
{
stream.Write(bData, 0, bData.Length);
}
}
catch (Exception ee)
{
Console.WriteLine(ee.ToString());
}
nextPage = "";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var vPage = new StreamReader(response.GetResponseStream()))
{
nextPage = vPage.ReadToEnd();
}
}
return cookies;
}
}
I have this code that creates a request and reads the data but it is always empty
static string uri = "http://yiimp.ccminer.org/api/wallet?address=DshDF3zmCX9PUhafTAzxyQidwgdfLYJkBrd";
static void Main(string[] args)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Get the stream associated with the response.
Stream receiveStream = response.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
Console.WriteLine("Response stream received.");
Console.WriteLine(readStream.ReadToEnd());
response.Close();
readStream.Close();
}
When i try to access the link from browser i get this json:
{"currency": "DCR", "unsold": 0.030825917365192, "balance": 0.02007306, "unpaid": 0.05089898, "paid24h": 0.05796425, "total": 0.10886323}
what am I missing?
When you perform the request from a browser there are a lot of headers that get sent to the web service. Apparently this web service validates the UserAgent. This is a decision on the part of the web service implementation, they might not want you to programmatically access it.
var client = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://yiimp.ccminer.org/api/wallet?address=DshDF3zmCX9PUhafTAzxyQidwgdfLYJkBrd"));
client.AutomaticDecompression = DecompressionMethods.GZip;
client.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063";
client.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";
client.Host = "yiimp.ccminer.org";
client.KeepAlive = true;
using (var s = client.GetResponse().GetResponseStream())
using (var sw = new StreamReader(s))
{
var ss = sw.ReadToEnd();
Console.WriteLine(ss);
}
Sending the headers seems to make it work.
I've tried many examples both here, and from Google and still cannot get my login saved. I've debugged and seen that it sends the 302 redirect and my login is successful. I believe. Then I send it to the next page, but keep the cookies gained from the login response. But I am still logged out. Here is my code aside from urls and login info. I've verified my POST parameters. I ask for the session cookie first, then login then proceed to the redirect page. All help is majorly appreciated, this is a huge headache.
HttpWebRequest GetRequest(string Site, CookieContainer Cookies, string SendType)
{
HttpWebRequest request = WebRequest.Create(Site) as HttpWebRequest;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36";
request.CookieContainer = Cookies; // Assign it some cookies
request.ContentType = "application/x-www-form-urlencoded";
request.Method = SendType;
return request;
}
private string GetLoggedInPage(string username, string password, string loginPage, string redirectPage)
{
string formParams = string.Format("login={0}&password={1}", username, password);
// cookies to use for multiple requests
var cookies = new CookieContainer(); // Create cookies!
var request= GetRequest(loginPage, cookies, "POST");
//Send params off
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
using (Stream loginStream = request.GetRequestStream())
{
loginStream.Write(bytes, 0, bytes.Length);
}
request.GetResponse().Dispose(); // removed some code here, no need to read response manually
request= GetRequest(redirectPage, cookies, "GET");
using (WebResponse getResponse = request.GetResponse())
{
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
var result = sr.ReadToEnd();//Read logged in webpage
return Convert.ToString(result);
}
}
return "<Html></html>"; //Return blank page in case the using above didn't work correctly.
}
The below code is refactored and working. I followed the advice of KoBE below, but it still wasn't working. The issue turned out to be targeting framework 4.5.2 I targeted the 4.0 and the below functions work. just send GetLoggedInPage your username, pass, and login url and target url and it'll give you a string back. I'm going to turn this into a class and use that.
Remember to save your cookies people!
void WriteParams(string Params, HttpWebRequest webrequestStream)
{
byte[] bytes = Encoding.ASCII.GetBytes(Params);
using (Stream requestStream = webrequestStream.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
}
HttpWebRequest GetRequest(string Site, ref CookieContainer Cookies, string SendType)
{
HttpWebRequest request = WebRequest.Create(Site) as HttpWebRequest;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36";
request.CookieContainer = Cookies; // Assign it some cookies
request.ContentType = "application/x-www-form-urlencoded";
request.Method = SendType;
return request;
}
private string GetLoggedInPage(string username, string password, string loginPage, string redirectPage)
{
string formParams = string.Format("login={0}&password={1}", username, password);
// cookies to use for multiple requests
var cookies = new CookieContainer(); // Create cookies!
HttpWebRequest request= GetRequest(loginPage, ref cookies, "POST");
//Send params off
WriteParams(formParams, request);
request.GetResponse();// .Dispose(); // removed some code here, no need to read response manually
request= GetRequest(redirectPage, ref cookies, "GET");
using (WebResponse getResponse = request.GetResponse())
{
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
var result = sr.ReadToEnd();//Read logged in webpage
return Convert.ToString(result);
}
}
return "<Html></html>"; //Return blank page in case the using above didn't work correctly.
}
Edit: I've finally looked at your code. Looks like you're simply missing the user-agent. See your modified code at the bottom.
First thing, I would change is this:
var cookies = new CookieContainer(); // Create cookies!
TheRequest.CookieContainer = new CookieContainer();
To this:
var cookies = new CookieContainer(); // Create cookies!
TheRequest.CookieContainer = cookies;
That will prevent you from needing:
foreach (Cookie c in TheResponse.Cookies)//Get response cookie
{
cookies.Add(c);
}
TheRequest.CookieContainer = cookies;
There is no need to create two cookie containers, then copy from one to the other, only to set the original to the copied version.
I'm not sure, but this could solve your problems depending on how much work the CookieContainer actually does in the background as far as Uri specific cookies, or what have you.
Is https://www.pucatrade.com/dashboard the url you're using? Also, why are you attempting to log in multiple times?
Modified Code
string username = "your-user";
string pass = "your-pass";
string loginPage = "https://pucatrade.com/login";
string redirectPage = "https://pucatrade.com/dashboard";
string formParams = string.Format("login={0}&password={1}", username, pass);
// cookies to use for multiple requests
var cookies = new CookieContainer(); // Create cookies!
var request = WebRequest.Create(loginPage) as HttpWebRequest;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36";
request.CookieContainer = cookies; // Assign it some cookies
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
request.ContentLength = bytes.Length;
using (Stream loginStream = request.GetRequestStream())
{
loginStream.Write(bytes, 0, bytes.Length);
}
request.GetResponse().Dispose(); // removed some code here, no need to read response manually
request = WebRequest.Create(redirectPage) as HttpWebRequest; //we know we get redirected too here, so just go there.
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36";
request.CookieContainer = cookies; // Assign it some cookies
request.Method = "GET";
using (WebResponse getResponse = request.GetResponse())
{
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
var result = sr.ReadToEnd();//Read logged in webpage
}
}
My current job is to consume a RESTful API with OAuth2. Currently I worked out how to get the access token and it is working ok while I use the chrome extension Rest Console, but when I try to do it from my application I always get the error that I am sending an invalid OAuth request. Below you can see three of the ways I tried to consume the API, but to no success. The page always returns error 500. Any help will be appreciated, if I had missed something crucial.
var auth = "Bearer " + item.access_token;
/* First Attempt */
var client = new RestClient("http://<link>");
var request = new RestRequest("sample", Method.GET);
request.AddHeader("Authorization", auth);
request.AddHeader("Content-Type", "application/json;charset=UTF-8");
request.AddHeader("Pragma", "no-cache");
request.AddHeader("User-Agent", "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36");
request.AddHeader("Accept", "application/json");
request.RequestFormat = DataFormat.Json;
var response = client.Execute(request);
var content = response.Content;
/* Second Attempt */
string sURL = "http://<link>/sample";
string result = "";
using (WebClient client = new WebClient())
{
client.Headers["Authorization"] = auth;
client.Headers["Content-Type"] = "application/json;charset=UTF-8";
client.Headers["Pragma"] = "no-cache";
client.Headers["User-Agent"] = "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36";
client.Headers["Accept"] = "application/json";
byte[] byteArray = Encoding.UTF8.GetBytes(parameters);
var result1 = client.DownloadString(sURL);
}
/* Third Attempt */
var request = (HttpWebRequest)WebRequest.Create(sURL);
request.Method = "GET";
request.ContentType = "application/json;charset=UTF-8";
request.Accept = "application/json";
request.Headers["Authorization"] = auth;
request.UserAgent = "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36";
string content;
HttpStatusCode statusCode;
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
var contentType = response.ContentType;
Encoding encoding = null;
if (contentType != null)
{
var match = Regex.Match(contentType, #"(?<=charset\=).*");
if (match.Success)
encoding = Encoding.GetEncoding(match.ToString());
}
encoding = encoding ?? Encoding.UTF8;
statusCode = ((HttpWebResponse)response).StatusCode;
using (var reader = new StreamReader(stream, encoding))
content = reader.ReadToEnd();
}
--------EDIT--------
For the first attempt I also tried to add the authentication to the client variable client.Authenticator = Authenticate; where OAuth2AuthorizationRequestHeaderAuthenticator Authenticate = new OAuth2AuthorizationRequestHeaderAuthenticator(item.access_token, item.token_type);
The code seems right. The fail attempts you did suggest that the issue is with the token and not the code. Bearer tokens have expiration time. So semms like your token expired between the first time you got it using chrome REST Console extension and when you wrote your code. But the strange situation here is the 500 error code you got. 401 is standard response when you token expired or not exist. 500 error code always mean server error.
I have a web site which i check my product list daily. I want to make a desktop program for it.
I need to login to the web site first then i go to site.com/v1/ProductList which is an xml document. I have managed to login with this code:
CookieCollection cookies = new CookieCollection();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(FirstURL);
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
//Get the response from the server and save the cookies from the first request..
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
cookies = response.Cookies;
string postData = "Username=x&Password=x&List=1&Submit=Submit";
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(cookies); //recover cookies First request
getRequest.Method = WebRequestMethods.Http.Post;
getRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
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();
}
Here i am successfully logged in.
But after this, if i create a new get request for my list(site.com/v1/ProductList) and get request it redirects me to the login page.
Edit: I just realized that i cant get any cookies after i login. It says "'enumeration yielded no results'".
I have no idea how to fix it right now.
Thanks
Change this line:
getRequest.AllowAutoRedirect = true;
to this:
getRequest.AllowAutoRedirect = false;
Make sure you actually set it to false and don't just delete the line because, by default, it gets set to true.