Reputation: 73
So I'm writing the client side user authentication code for my Web API ReST service.
This is how the request and response should look like and I've written this code to register a user and it works fine.
Http Request:
POST https://localhost:44305/api/Account/Register HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: https://localhost:44305/
Content-Length: 84
{"Email":"[email protected]","Password":"Password1!","ConfirmPassword":"Password1!"}
Http Response:
HTTP/1.1 200 OK
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 00:57:58 GMT
Content-Length: 0
Code to accomplish this:
byte[] data = Encoding.UTF8.GetBytes("{\"Email\":\"[email protected]\"," + "\"Password\":\"Password1!\"," + "\"ConfirmPassword\":\"Password1!\"}");
WebRequest request = WebRequest.Create("http://localhost:8091/api/Account/Register");
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.ContentLength = data.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
string responseContent = null;
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader sr99 = new StreamReader(stream))
{
responseContent = sr99.ReadToEnd();
}
}
}
Console.WriteLine(responseContent);
This works fine and the user account is created in the database but I don't get the response.
The next problem is sending sending the login details to get a bearer token? How can I do this?
This is what the request and response should look like
HTTP REQUEST FOR AUTHENTICATION:
POST https://localhost:44305/Token HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://localhost:44305/
Content-Length: 68
grant_type=password&username=alice%40example.com&password=Password1!
HTTP RESPONSE FOR AUTHENTICATION:
HTTP/1.1 200 OK
Content-Length: 669
Content-Type: application/json;charset=UTF-8
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 01:22:36 GMT
{
"access_token":"imSXTs2OqSrGWzsFQhIXziFCO3rF...",
"token_type":"bearer",
"expires_in":1209599,
"userName":"[email protected]",
".issued":"Wed, 01 Oct 2014 01:22:33 GMT",
".expires":"Wed, 15 Oct 2014 01:22:33 GMT"
}
SO how can I send a request for a token?
Upvotes: 1
Views: 15254
Reputation: 1086
I'd kindly like to suggest you using HttpClient if you're going for your own http rest client in your app.
HttpClient
and Json.net:public class TokenResponse
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_in { get; set; }
public string userName { get; set; }
public string issued { get; set; }
public string expires { get; set; }
}
private async Task Login()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://localhost:44305");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", "[email protected]"),
new KeyValuePair<string, string>("password", "password1")
});
var result = await client.PostAsync("/token", content);
string resultContent = await result.Content.ReadAsStringAsync();
var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(resultContent);
}
}
HttpWebRequest
:If this is the case, your solution might look something like the following.
private void Login()
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://localhost:44305/Token");
request.Method = "POST";
request.AllowAutoRedirect = false;
request.Accept = "*/*";
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
StringBuilder postData = new StringBuilder();
postData.Append("grant_type=" + HttpUtility.UrlEncode("password") + "&");
postData.Append("username=" + HttpUtility.UrlEncode("[email protected]") + "&");
postData.Append("password=" + HttpUtility.UrlEncode("password"));
using (StreamWriter stOut = new StreamWriter(request.GetRequestStream(), Encoding.UTF8))
{
stOut.Write(postData);
stOut.Close();
}
}
Now Im not sure where and how you are trying this. If you're invoking this from a console application main
method, make sure the following so you don't have to come back to the same asynchronous context and this should always be invoked from an async method itself:
var result = await client.PostAsync("https://localhost:44305/token", content).ConfigureAwait(false);
I updated my solution in a github gist. It's working for me as it's trying to post the request right away.
Upvotes: 4