I am preparing a windows application in that I want to use oAuth2 to access info from google plus.
But I am getting bad request for my following code.. I am able to create app in google console and fetch the "code" for application access.
WebRequest request = WebRequest.Create(
GoogleAuthenticationServer.Description.TokenEndpoint
);
// You must use POST for the code exchange.
request.Method = "POST";
// Create POST data.
string postData = FormPostData(code);
byte[] byteArray = Encoding.UTF8.`enter code here`GetBytes(postData);
// Set up the POST request for the code exchange.
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
// Perform the POST and retrieve the server response with
// the access token and/or the refresh token.
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
// Convert the response JSON to an object and return it.
return JsonConvert.DeserializeObject<OAuthResponseObject>(
responseFromServer);
Now, I am trying to use that code to get the access token. .which is giving me BAD request.
I also followed few post on stackoverflow. but none of them working for me.
Thanks
EDIT:
Thanks for the reply. I was able to do it my own somehow :)
i think you can begin this way :
Google plus OAuth
For web applications, I would strongly recommend you use a one-time-code flow as demonstrated in the Google+ Quickstart sample. Please try working through the Quickstart instructions to make sure you're not missing any steps. When you do Google+ Sign-In this way, you will be able to get over-the-air installs of Android apps (if you have one for your site) and will be applying best practices for authorization.
All of the code for doing this is available in the sample which also demonstrates integration with the Google client libraries - this opens up access to all of the Google APIs and product integrations.
From Windows apps or installed apps, you would need to do more of the heavy lifting yourself. The following blog article covers how you could do the authorization in legacy scenarios:
http://gusclass.com/blog/2012/08/31/using-the-google-net-client-library-with-google/
There is an example as well:
http://gusclass.com/projects/PlusDotNet.zip
A couple notes:
When you create your client ID, make sure it's for an installed application.
The authorization code is taken from the window title after the user authorizes; this is a little dodgy and you should be doing this in a window you host in your app.
Performing authorization this way will not allow you to have over-the-air installs to Android. For doing this, you could possibly host a webview inside of the application and use that for a one-time-code flow but I have never seen this working from Windows.
I was able to do it my own using following code..
private void button2_Click(object sender, EventArgs e)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
authLink.AppendFormat("code={0}", code);
authLink.AppendFormat("&client_id={0}", "996688211762.apps.googleusercontent.com");
authLink.AppendFormat("&client_secret={0}", "nprfJuBUOyU2hsb3tqt1XDnB");
authLink.AppendFormat("&redirect_uri={0}", "urn:ietf:wg:oauth:2.0:oob");
authLink.Append("&grant_type=authorization_code");
UTF8Encoding utfenc = new UTF8Encoding();
byte[] bytes = utfenc.GetBytes(authLink.ToString());
Stream os = null;
try // send the post
{
webRequest.ContentLength = bytes.Length; // Count bytes to send
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length); // Send it
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
try // get the response
{
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
if (webResponse == null) { MessageBox.Show("null"); }
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
textBox1.Text = sr.ReadToEnd().Trim();
//MessageBox.Show(sr.ReadToEnd().Trim());
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
private void button1_Click(object sender, EventArgs e)
{
StringBuilder authLink = new StringBuilder();
authLink.Append("https://accounts.google.com/o/oauth2/auth");
authLink.AppendFormat("?scope={0}", "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile");
authLink.AppendFormat("&client_id={0}", "xxxxxx.apps.googleusercontent.com");
authLink.AppendFormat("&redirect_uri={0}", "urn:ietf:wg:oauth:2.0:oob");
authLink.Append("&response_type=code");
string u = #"https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=xxxxxxxx.apps.googleusercontent.com";
webBrowser1.Navigate(u);
}
I am assuming to have two button on window.. button1 is used to get CODE from google and button2 uses that code and get the access_token which is what I was looking for.
Related
I am currently developing in Unity (in particular using C#) and I'm stuck with HttpWebRequest - HttpWebResponse random timeouts.
I have some methods that send a POST request to a server I host on my local machine (XAMPP) to use various php scripts which are going to fetch informations from MySQL Database (hosted with XAMPP) and give back those info in JSON format.
Then I handle these JSON informations with my C# scripts.
The problem is that when I run the first test all is good:I can get the JSON data from my Server and show it in the Debug Console.
When I run the second test,a WebException is raised with error:
WebException - The request timed out
After that second test,if I run again and again,the problem keeps presenting in a random way.
I followed all the guidelines I found on the internet on how to setup a webrequest - webresponse properly,in particular I tried to use ServicePoint.DefaultConnectionLimit and ServicePoint.MaxServicePointIdleTime,without any result.
The general structure of my methods (regarding the web request/response part) is something like that:
public void WebMethod(){
string post_url = "http://localhost/service.php?someparam=1&someparam=2";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(post_url);
request.Method = "POST";
request.KeepAlive = false;
request.Timeout = 5000;
request.Proxy = null;
string Response = "";
try
{
using (HttpWebResponse resp = request.GetResponse() as HttpWebResponse)
{
using (Stream objStream = resp.GetResponseStream())
{
using (StreamReader objReader = new StreamReader(objStream, Encoding.UTF8))
{
Response = objReader.ReadToEnd();
objReader.Close();
}
objStream.Flush();
objStream.Close();
}
resp.Close();
}
}catch(WebException e)
{
Debug.Log(e.Message);
}
finally
{
request.Abort();
}
//tried this one after reading some related answers here on StackOverflow,without results
//GC.Collect();
Debug.Log("SERVER RESPONSE:" + Response);
//Response Handling
}
I know that it may be something related to a wrong abort on the HttpWebRequest / Response or maybe related to the HTTP 1.1 connections limit,but I can't figure out any solution at the moment.
Any help is appreciated.
I have one Windows Handheld device application on .Net framework 3.5 which has the requirement of accessing a REST API. The REST API gives me JSON output which I am going to process later. I have the following code for that:-
HttpWebRequest webRequest;
string result = String.Empty;
try
{
webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.KeepAlive = false;
webRequest.ContentType = "application/x-www-form-urlencoded";
using (WebResponse response = webRequest.GetResponse())
{
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
}
catch (Exception ex)
{
result = ex.Message;
}
The url variable is holding the url for the API with some query parameters in it.
For Example "http://www.something.com/Login?id=test&pwd=test".
Now my problem is I dont want to use the query string parameters rather I want to use Request parameters because the above approach does not work every time perfectly. Some times I get an "Unauthorized" error. And also I have one tokenId which I need to send everytime I am calling the API and the token Id is in base64 format.
Can anyone please help me how can I use the Request Parameter feature to send the parameter values?
use the Headers property of your request object.
webRequest.Headers.Add("id", "test");
webRequest.Headers.Add("pwd", "test");
webRequest.Headers.Add("token", myToken);
I am working on a simple Windows Forms program that take a username and password from a "Textbox" then it show my linked-in name in a "Messagebox".
I want to accomplish the code with the using of "HttpWebRequest" or using any method to send my POST request to Linked-in then i can get the response and find my name to shown it in a "Messagebox".
I am familiar with creating a "GET" Request and also i made some "POST" Requests but in this case i didn't know how can i send my "txt_UserName.Text" and "txt_Password" with the POST Request and how can i receives the Response.
I tried to using Fiddler to capture POST request (=POST) from linkedin when i try to login but it captures more than 4 requests when i see the header of them it seem like a GET Request this is an example of one:
GET /nhome/?trk= HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
and all of them have a multiple cookies values.
This is my POST request code:
public void SubmitData()
{
try
{
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("http://www.linkedin.com");
// Set the Method property of the request to POST.
request.Method = "POST";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
//Content Length
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader sr = new StreamReader(dataStream);
MessageBox.Show(sr.ReadToEnd());
sr.Close();
dataStream.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
Now the only thing i wish to know, how can i send my username and password as a values to login to linked-in?
Edit:
Below is my second try, it's ok, i can now send the User and Password in postData and i can store the Cookies and retrive it. but there are two issues:
1- how can i make sure that the login is accomplished and not failed
2- if the login is accomplished i want to know what is the second step to get my name from profile, is it made another request or what ?
private void button1_Click(object sender, EventArgs e)
{
PostMessage();
}
private void PostMessage()
{
try {
// POST Data and the POST uri
string postData = "isJsEnabled=true&source_app=&session_key=" + textBox1.Text + "&session_password=" + textBox2.Text + "&signin=Sign+In&session_redirect=";
string uri = "https://www.linkedin.com/uas/login-submit";
// Encoding the POST Data
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Create the POST Request
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(uri);
//POST Parameters (Method and etc.)
WebReq.Method = "POST";
WebReq.ContentType = "application/x-www-form-urlencoded";
WebReq.ContentLength = byteArray.Length;
// Set the POST Request Cookies
var cookieContainer = new CookieContainer();
WebReq.CookieContainer = cookieContainer;
// Get the request stream.
Stream dataStream = WebReq.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
HttpWebResponse response = (HttpWebResponse)WebReq.GetResponse();
dataStream = response.GetResponseStream();
StreamReader sr = new StreamReader(dataStream);
//MessageBox.Show(sr.ReadToEnd());
sr.Close();
dataStream.Close();
if (response.StatusCode != HttpStatusCode.OK)
{
MessageBox.Show(" Error: " + response.StatusDescription);
response.Close();
}
foreach (Cookie cook in response.Cookies)
{
MessageBox.Show(cook.Name + " " + cook.Value);
}
}
catch (Exception ex)
{
MessageBox.Show("POST Message Error: " + ex.Message);
}
}
I used Fiddler while I was logging in and found a request to https://www.linkedin.com/uas/login-submit containing the username and password. Found it? Now, if you want to look at it completely from an HTTP Request perspective, you will have to figure out how to generate the other data in the post data/cookie header using the other requests and responses that your browser sent and received to and from the site before this particular request (the information should be there). I think this will lead you to what you need to do, but there's some work to be done!
You're going to need more than you think to log in there is good documentation on how to do this just here, you are going to need an auth token etc, This is because like other services, for example google, they are using oauth2 to secure applications etc.
oauth works by issuing tokens and refreshing tokens and there's a bit of a learning curve but its not especially difficult.
Essentially the following happens
You register your application with linked in and they give you a
client secret.
You pass this code to linked in in your application
and they will generate an auth screen saying that the application is
requesting permission.
you then approve this and it will give you an access token
You then log in with the access token (access tokens on linkedin are valid for 60 days, you must refresh them by this time).
On the plus side the linked in api is pretty straight forward and once authorised you will be able to get stuff pretty easily. All of this is detailed in the link provided in nice step by step stages.
By the way there is also a nuget package that gives you access to profile information.
Try Install-Package LinkedIn
I should point out that the nuget package above gives you a login provider to help authenticate if you don't want to roll your own.
Added after your comments below.
If all you want to do is know how to send a post request here's a generic bit of code that does just that:
string url = "www.foo.bar.com";
using (var webClient= new WebClient())
{
var data = new NameValueCollection();
data["username"] = "<yourusername>";
data["password"] = "<yourPassword>";
var response = webClient.UploadValues(url, "POST", data);
}
note: because its a web uri you should use POST in the method argument here.
The problem you up against is that Linkedin uses a redirect within the login session and is differcult to catch.
So somehow within the login session you need to code that it redirects to the https://www.linkedin.com/nhome/?trk= this provides the user page access.
I am also testing with this, however did not manage to figure this part out, normally
httpWebRequest.AllowAutoRedirect = true;
should do the trick but not in this case it does not work.
So if you find the solution let me know, if I find will post it also.
I am new to WCF and Rest services, and tried to do some implementation from posts I found on the web, but I am still getting some problems.
So let me explain my scenario.
I have a WPF application, and in it I have a feedback form, which the client can fill up, attach some screenshots, and send it. Now my idea was to gather all this info inside an XML file, which I am already doing successfully, and then uploading this XML file on my server in a particular folder.
Now as I understand it, the client app has to have a POST method to post the stream to the server, and then I should have an aspx page on the server to decode back the stream I get from the POST, and formulate my XML file, and then save it inside the folder, correct me if I'm wrong.
At the moment I have implemented the code on the client as follows :-
public static void UploadFile()
{
serverPath = "http://localhost:3402/GetResponse.aspx";
filePath = "C:\\Testing\\UploadFile\\UploadFile\\asd_asd_Feedback.xml";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverPath);
//request.MediaType = "text/xml";
request.ContentType = "text/xml";
//request.Method = "POST";
request.Method = "POST";
//request.ContentLength = contentLength;
//request.ContentType = "application/x-www-form-urlencoded";
using (FileStream fileStream = File.OpenRead(filePath))
using (Stream requestStream = request.GetRequestStream())
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int byteCount = 0;
while ((byteCount = fileStream.Read(buffer, 0, bufferSize)) > 0)
{
requestStream.Write(buffer, 0, byteCount);
}
}
string result = String.Empty;
try
{
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
}
catch (Exception exc)
{
}
if (result == "OK")
{
}
else
{
// error...
}
}
Now how can I pass the requestStream to the GetResponse.aspx page? And is this the correct way to go?
Thanks for your help and time
I don't understand what your code is trying to do. Have you considered actually using a WCF client and a WCF service for doing the actual upload itself?
There is a sample that does this! This blog post details how to use the programming model on the service side, and this follow-up blog post details how to use it on the client side. I've seen it used quite a bit for file upload and image transfer scenarios, so it might help your situation as well! The example present in those blog posts is a file upload one.
Hope this helps!
Although i can grasp the concepts of the .Net framework and windows apps, i want to create an app that will involve me simulating website clicks and getting data/response times from that page. I have not had any experience with web yet as im only a junior, could someone explain to me (in english!!) the basic concepts or with examples, the different ways and classes that could help me communicate with a website?
what do you want to do?
send a request and grab the response in a String so you can process?
HttpWebRequest and HttpWebResponse will work
if you need to connect through TCP/IP, FTP or other than HTTP then you need to use a more generic method
WebRequest and WebResponse
All the 4 methods above are in System.Net Namespace
If you want to build a Service in the web side that you can consume, then today and in .NET please choose and work with WCF (RESTfull style).
hope it helps you finding your way :)
as an example using the HttpWebRequest and HttpWebResponse, maybe some code will help you understand better.
case: send a response to a URL and get the response, it's like clicking in the URL and grab all the HTML code that will be there after the click:
private void btnSendRequest_Click(object sender, EventArgs e)
{
textBox1.Text = "";
try
{
String queryString = "user=myUser&pwd=myPassword&tel=+123456798&msg=My message";
byte[] requestByte = Encoding.Default.GetBytes(queryString);
// build our request
WebRequest webRequest = WebRequest.Create("http://www.sendFreeSMS.com/");
webRequest.Method = "POST";
webRequest.ContentType = "application/xml";
webRequest.ContentLength = requestByte.Length;
// create our stram to send
Stream webDataStream = webRequest.GetRequestStream();
webDataStream.Write(requestByte, 0, requestByte.Length);
// get the response from our stream
WebResponse webResponse = webRequest.GetResponse();
webDataStream = webResponse.GetResponseStream();
// convert the result into a String
StreamReader webResponseSReader = new StreamReader(webDataStream);
String responseFromServer = webResponseSReader.ReadToEnd().Replace("\n", "").Replace("\t", "");
// close everything
webResponseSReader.Close();
webResponse.Close();
webDataStream.Close();
// You now have the HTML in the responseFromServer variable, use it :)
textBox1.Text = responseFromServer;
}
catch (Exception ex)
{
textBox1.Text = ex.Message;
}
}
The code does not work cause the URL is fictitious, but you get the idea. :)
You could use the System.Net.WebClient class of the .NET Framework. See the MSDN documentation here.
Simple example:
using System;
using System.Net;
using System.IO;
public class Test
{
public static void Main (string[] args)
{
if (args == null || args.Length == 0)
{
throw new ApplicationException ("Specify the URI of the resource to retrieve.");
}
WebClient client = new WebClient ();
// Add a user agent header in case the
// requested URI contains a query.
client.Headers.Add ("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
Stream data = client.OpenRead (args[0]);
StreamReader reader = new StreamReader (data);
string s = reader.ReadToEnd ();
Console.WriteLine (s);
data.Close ();
reader.Close ();
}
}
There are other useful methods of the WebClient, which allow developers to download and save resources from a specified URI.
The DownloadFile() method for example will download and save a resource to a local file. The UploadFile() method uploads and saves a resource to a specified URI.
UPDATE:
WebClient is simpler to use than WebRequest. Normally you could stick to using just WebClient unless you need to manipulate requests/responses in an advanced way. See this article where both are used: http://odetocode.com/Articles/162.aspx