I recently have to build a little contact form that will post to an API. The application will need to firstly authenticate to the API with OAuth to get a token. It then uses that token to post the form to the API. The token will be valid for a number of seconds defined in the authentication response.
I decide to use RestSharp to make HTTP request to the API. Restsharp is a simple and easy-to-use REST and HTTP API client for .NET.
First, download and reference RestSharp from Nuget. I then create a model that maps to the response from the API after the authentication. The response model contains 3 properties as below (specified in the API documentation)
/// <summary> /// The implementation of the authentication response from API /// </summary> public class ApiAuthenticationResponse { /// <summary> /// The access token. /// </summary> public string access_token { get; set; } /// <summary> /// The type of the token. /// </summary> public string token_type { get; set; } /// <summary> /// The token expiry in seconds. /// </summary> public int expires_in { get; set; } }
Since the token is valid for a period of time, I don’t want to authenticate to the API until I have to after the first time. The token will be cached in memory for as long as it is valid. The application will authenticate to the API again when the token expires. Below is the method to get the token and only authenticate to the API when required.
private string apiLocation = ""; // The api location goes here private string username = ""; // The api username goes here private string password = ""; // The api username goes here /// <summary> /// Gets authentication token from the API /// <remarks>Gets from cach, if expired then re-authenticate with api and set to cache.</remarks> /// </summary> /// <returns> /// The token. /// </returns> private string GetAuthenticationToken() { var token = (string)this.HttpContext.Cache["ApiAuthenticationToken"]; if (string.IsNullOrWhiteSpace(token)) { var client = new RestClient(this.apiLocation) { Authenticator = new HttpBasicAuthenticator(this.username, this.password) }; var request = new RestRequest("oauth/token", Method.GET) { RequestFormat = DataFormat.Json }; request.AddParameter("grant_type", "client_credentials"); var response = client.Execute<ApiAuthenticationResponse>(request); if (response.StatusCode == HttpStatusCode.OK) { token = response.Data.access_token; this.HttpContext.Cache.Insert("ApiAuthenticationToken", token, null, DateTime.UtcNow.AddSeconds(response.Data.expires_in), Cache.NoSlidingExpiration); } else { throw response.ErrorException; } } return token; }
So now when I post the contact form to the API, I just need to call the above method to get the authentication token and add it to the header.
/// <summary> /// The implementation of the contact form model. /// </summary> public class ContactFormModel { /// <summary> /// The first name. /// </summary> public string FirstName { get; set; } /// <summary> /// The last name. /// </summary> public string LastName { get; set; } /// <summary> /// The email address. /// </summary> public string Email { get; set; } /// <summary> /// The phone. /// </summary> public string Phone { get; set; } /// <summary> /// The message. /// </summary> public string Message { get; set; } } public void Submit(ContactFormModel model) { var client = new RestClient(this.apiLocation); var request = new RestRequest("contactUs", Method.POST) { RequestFormat = DataFormat.Json }; request.AddHeader("Authorization", string.Format("bearer {0}", this.GetAuthenticationToken())); request.AddHeader("Accept", "application/json"); request.AddParameter("application/json", JsonConvert.SerializeObject(model), ParameterType.RequestBody); var result = client.Execute(request); if (result.StatusCode != HttpStatusCode.OK) { throw result.ErrorException; } }
That’s it, very simple. There are a few things new that I learn after implementing this.
- I’ve used RestSharp to make web request to API before but I’ve never authenticated with an API with OAuth. It was always appending the API key as the parameter to the request. I don’t want the browser to prompt me for username and password when making the request so I have to figure out a way to pass the username and password with the request. With RestSharp, it was as simple as setting the Authenticator in the client.
var client = new RestClient(this.apiLocation) { Authenticator = new HttpBasicAuthenticator("username", "password") };
If you don’t use RestSharp, that is same as adding Authorization header to the request.
var request = WebRequest.Create("http://www.contoso.com/"); // dXNlcm5hbWU6cGFzc3dvcmQ= is the Base64 string of username:password request.Headers.Add("Authorization", "Basic dXNlcm5hbWU6cGFzc3dvcmQ=");
- I notice a strange thing when I make web request to the test API URL which does not have https. Fiddler shows that there is 301 Permanently Moved to the same URL but with https. That is fine except that when it’s moved, it also loses all the headers which results in an unauthorized response due to not having the Authorization header. I end up just making request directly to the test URL with https. I’m not sure whether this is because of the API backend not handling redirect requests well or it’s something to do with RestSharp or Fiddler.
- A colleague recommends a Chrome extension which allows you to easily test your API. The extension is called Advanced REST client. You can specify any headers that you like. Great tool.
izhar
Great work
.
It was an informative article.