mapmyindia confused about how to get OAuth - mapmyindia-api

I have read the documentation for OAuth on this website.
But I am still confused about the format in which the request url is supposed to be in.
Any help would be amazing.

You may use the following request url to generate the Access Token,
String URL = "https://outpost.mapmyindia.com/api/security/oauth/token?grant_type=client_credentials&client_id="+clientid+"&client_secret="+clientsecret;
And, add the following Headers in the POST Method,
("accept", "application/json")
("Content-Type", "application/x-www-form-urlencoded")
If you are using Volley Library to get the Access Token using the POST request,
you may pass the parameters as a HashMap as follows:
Map<String, String> params = new HashMap<String, String>();
params.put("accept", "application/json");
params.put("Content-Type", "application/x-www-form-urlencoded");

It looks like they use Spring. And it requires grant_type to be passed as application/x-www-form-urlencoded. And the credentials in a header:
{
'Authorization': `Basic ${base64Encode(clientId:clientSecret)}`,
}

Related

How to add parameter to HttpWebRequest

I'm trying to get some data from Spotify's API, but I receive some errors from compilator and I think it may happen because I didn't add parameter grant_type=client_credentials.
The question is how can I add this parameter into HttpWebRequest object?
var token = GetToken();
var request = HttpWebRequest.CreateHttp($"{BaseAddress}search?q=Batman&type=playlist&market=US&limit=10&offset=5&access_token={token}");
request.Method = WebRequestMethods.Http.Get;
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " + token);
request.ContentType = "application/json";
request.Accept = "application/json";
When you get the Token is where you need to add this parameter, your GetToken method will be sending the Client Credentials Flow of the Client Id and Client Secret and it is there where the grant_type of client_credentials needs to be sent as a HttpWebRequest with the ContentType of application/x-www-form-urlencoded this is what the documentation refers to as a Request Body Parameter.
I've used HttpClient that allows FormUrlEncodedContent to do this but you should be able to send that information using HttpWebRequest the way you are doing it with a POST request but the GetToken code will need to be modified, that isn't shown in the question

Trustpilot Api - Get Private Product Review always returns Unauthorised response status

I hope someone can help me.
I am trying to retrieve a Product Review for a product using the Trustpilot Api's and am having some success but not getting the results I would expect.
The approach I have taken is as follows:
Get an OAUTH2 token - (Returns a successful response)
Retrieve my business units from a config file and for each business unit get the product reviews using the endpoint: https://api.trustpilot.com/v1/private/business-units/{business-unit}/review?token={OAUTH2 token from step 1} - (Returns a successful response)
For each product review I attempt to retrieve the product review detail. For this I have a couple of options.
(i) Each product review has meta-links and so I can get the product review using the corresponding meta-link and tagging the apikey on e.g. https://api.trustpilot.com/v1/reviews/1234567890abcdefg?apikey={apikey} where the apikey is the one provided up when I registered for a developer account - (Returns a successful response)
(ii) Call the endpoint as documented in the developers.trustpilot.api website (https://developers.trustpilot.com/product-reviews-api#get-private-product-review) : https://api.trustpilot.com/v1/private/product-reviews/{reviewId} - (Returns an Unauthorised status code)
For option (ii) above I have tried multiple ways of passing the apikey (according to the documentation, the endpoint requires the apikey as authorisation.
I am using C# as the language for accessing the Trustpilot apis so the following snippets are how I have tried to call the method.
Set the GetProductReview endpoint as follows:
var url = $"https://api.trustpilot.com/v1/private/product-reviews/" + review.Id.ToString();
using (var client = new HttpClient())
{
var uri = new Uri(url, UriKind.Absolute);
client.BaseAddress = uri;
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new system.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("apikey", apiKey);
try
{
var response = client.GetAsync(uri).Result;
.
.
.
In the above code snippet, the apikey is passed in to the method and passed to the endpoint as a RequestHeader value.
Set the endpoint as follows:
var url = $"https://api.trustpilot.com/v1/private/product-reviews/" + review.Id + $"?apikey={apiKey}";
and call the HttpClient as follows:
using (var client = new HttpClient())
{
var uri = new Uri(url, UriKind.Absolute);
client.BaseAddress = uri;
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
try
{
var response = client.GetAsync(uri).Result;
.
.
.
In both cases I receive an HttpStatus 401 - Unauthorized.
The documentation indicates that I should pass the apikey (which I have done in two different ways).
I have also tried calling the endpoint replacing the ?apikey={apiKey} with ?token={token} in case the documentation is incorrect and requires a token.
Additionally, I have also tried passing the token as a RequestHeader value and receieve the same result (Unauthoirised)
I would really like to use the endpoint:
https://api.trustpilot.com/v1/private/product-reviews/{review}
as this returns more information (for example the sku which would allow me to get access back to the product).
Can anyone please tell me where I am going wrong here?
Thanks in advance
The documentation for the /v1/private/product-reviews/{reviewId} endpoint is indeed incorrect, since it actually requires a Business user OAuth Token instead of an API Key.
In this case, you have two options (and the first one you have used before for the /v1/private/business-units/{businessUnitId}/reviews endpoint):
You can pass the access token in the query string: /v1/private/product-reviews/{reviewId}?token={token}. You mentioned you have tried this. Maybe it did not work for you because your token expired before you tried this approach. Can you try again after refreshing the token?
You can also pass the access token as a Bearer authorization header:
var url = $"https://api.trustpilot.com/v1/private/product-reviews/{review.Id.ToString()}";
using (var client = new HttpClient())
{
...
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
...
}
In any case, you caught an error in the documentation that should be fixed soon. As a rule of thumb, all private endpoints (the ones that have /private/ in the path) require a Business user OAuth Token.
EDIT: The documentation for the /v1/private/product-reviews/{reviewId} endpoint has been fixed. Now it shows that a Business user OAuth Token is required.

Using httpClient.postasync for web api calls .netcore

I am new to .netcore, I am working on web api that are running on docker container and while using postman the web api's are working really fine outputting the results. I want to make a program in .netcore calling the webapi endpoints and getting the response and using that particular response in other endpoints with MVC.
The explanation is given below.
The default username and password for admin is default set for example username:admin , password: helloworld
. The first time admin login the api requires a new personal password as shown in the Postman figure below.
The login api is: localhost://..../v1/users/login
The first question is How to give the values in Authorization->BasicAuth using .netcore.
The body of the api looks like the figure below.
After setting the new_password the response of the api is a token as given below.
The particular token is then use in the Environment to create user. The image for more clear problem is given below.
Lastly, the token then used to make other API calls such as creating a user.
API: https://localhost/..../v1/users
The image is below.
As a newbie in .netcore language, I am really struggling to do this kind of API calls, as most of the tutorials I tried are generating their own token from API, but here I just want to take the response token and save it and then use it in other API calls.
The StackOverflow community's support was always really handy for me.
The Code I'm trying is given below.
**Controller**
public class Login_AdminController : ControllerBase
{
[Route("/loginAdmin")]
[HttpPost]
public async Task<string> LoginAdminAsync([FromBody] dynamic content)
{
LoginAdmin L = new LoginAdmin();
var client = new HttpClient();
client.BaseAddress = new Uri("https://localhost:9090");
var request = new HttpRequestMessage(HttpMethod.Post, "/v1/users/login");
var byteArray = new UTF8Encoding().GetBytes($"<{L.username}:{L.df_Password}>");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var formData = new List<KeyValuePair<string, string>>();
formData.Add(new KeyValuePair<string, string>("new_password", "helloWorld123!"));
request.Content = new FormUrlEncodedContent(formData);
var response = await client.SendAsync(request);
Console.WriteLine(response);
return content;
}
}
}
***Model***
public class LoginAdmin
{
public string username = "admin";
public string df_Password = "secret";
public string new_Password { get; set; }
}
Thank you.
Do you want to get token from response? If yes. Try this:
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:12345/Api");
var request = new HttpRequestMessage(HttpMethod.Post, "/token");
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("username", "yourusername"));
keyValues.Add(new KeyValuePair<string, string>("password", "yourpassword"));
request.Content = new FormUrlEncodedContent(keyValues);
var response = client.SendAsync(request).Result;
return response.Content.ReadAsStringAsync().Result;
Authorization is handled via the Authorization request header, which will include a token of some sort, prefixed by the scheme. What you're talking about here isn't really basic auth. With that, you literally pass the username and pass in the Authorization header with each request. What you're doing is just authenticating once to get an auth token, and then using that auth token to authorize further requests. In that scenario, you should really be posting the username and pass in the request body. Then, you'd do bearer auth with the token for the other requests, using the Authorization header. Still, to cover both bases:
Basic Auth
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}"));
request.Headers.Add("Authorization", $"Basic {token}");
Bearer Auth
request.Headers.Add("Authorization", $"Bearer {token}");
// where `token` is what was returned from your auth endpoint
FWIW, List<KeyValuePair<string, string>> is just Dictionary<string, string>. It's better to use the real type. Then, you can just do formData.Add("new_password", "helloWorld123!") instead of formData.Add(new KeyValuePair<string, string>("new_password", "helloWorld123!"))

Survey Monkey is Giving me an Invalid Authorization in Request Header Error

I am using the .NET HttpClient in xamarin forms to try to connect to survey monkey. I am new to HttpClient, Xamarin, REST, and survey monkey so I could be making mistakes anywhere or everywhere.
I've had some success using the survey monkey examples with curl and I am trying to convert that to C# code with HttpClient.
I have some "test code" like
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("https://api.surveymonkey.net/v2/surveys/get_survey_list?api_key=humkanu389g5dp9tvsdrh8fv");
HttpContent content = new StringContent(String.Empty,Encoding.UTF8,"application/json");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization","Bearer XXXXXXXXX");
httpClient.Timeout = TimeSpan.FromSeconds(10);
HttpResponseMessage response = Task.Run(() => httpClient.PostAsync(uri,content)).Result;
String responseContent = Task.Run(() => response.Content.ReadAsStringAsync()).Result;
In my code, I have replaced the XXXXXXX's with my authorization token.
But I am getting a response like
{"status":1,"errmsg":"Invalid \"Authorization\" data in request header"}
I am wondering if I am handling the AuthenticationHeaderValue() part wrong. Or something else?
Your header is not in the correct format, you have "Authorization bearer XXXXX" as the value. So it looks like this:
Authorization: Authorization bearer XXXXX
I'm not sure why based on your code, you should debug and see the value you are sending out. But it should be:
Authorization: bearer XXXXX
My assumption is AuthenticationHeaderValue is doing something you're not expecting. Searching the docs it looks like you're doing it right - so I'm not sure exactly what's wrong with the C# code, just that the header you're sending out is not correct.
General Kandalaft really pointed out the problem--which in retrospect was obvious, but I want to post the final code here in case someone else is trying this.
I ended up fixing the AuthenticationHeaderValue as pointed out above. Then I ran into a problem because my request content was an empty string. I put in some json text from an example and it worked. So the final code
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("https://api.surveymonkey.net/v2/surveys/get_survey_list?api_key=humkanu389g5dp9tvsdrh8fv");
HttpContent content = new StringContent ("{ \"fields\": [ \"title\", \"date_modified\" ] }",Encoding.UTF8,"application/json");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer","XXXXXX");
httpClient.Timeout = TimeSpan.FromSeconds(10);
HttpResponseMessage response = Task.Run(() => httpClient.PostAsync(uri,content)).Result;
String responseContent = Task.Run(() => response.Content.ReadAsStringAsync()).Result;

OAuth 2.0 authentication in RestSharp

I am trying to authenticate RESTful service (sabre REST api) using RESTsharp library but i am not able to authenticate it. I am using my Client id and secret. Please tell me how to authenticate using oAuth 2.0 authenticator.
I have tried this code. ( sabre is using OAuth 2.0 authentication )
public ActionResult Index()
{
var client = new RestClient("https://api.test.sabre.com");
client.Authenticator = new HttpBasicAuthenticator("myclientid", "myclientsecret");
RestRequest request = new RestRequest("/v1/auth/token", Method.POST);
request.AddHeader("Authorization", "Basic " + client);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials");
IRestResponse response = client.Execute(request);
var content = response.Content;
ViewBag.R = content;
return View();
}
i got this result
{"error":"invalid_client","error_description":"Credentials are missing or the syntax is not correct"}
please tell what i am doing wrong.
Thanks
Snapshot of Fiddler Comparison of Running code (not with RestSharp) and code using RestSharp is shown
With RestSharp
Seems to me like you are adding the Authorization header twice. The documentation here says
The authenticator’s Authenticate method is the very first thing called
upon calling RestClient.Execute
Looking at the implementation of HttpBasicAuthenticator, the Authenticate method adds the appropriate header to the request.
So remove the following line from your example:
request.AddHeader("Authorization", "Basic " + client);
You need to first obtain access token from Sabre that you can later use while making rest api calls.
The access token POST request looks like this:
POST https://api.test.sabre.com/v2/auth/token
Authorization: Basic ZVc5MWNtTnNhV1Z1ZEdsazplVzkxY21Oc2FXVnVkSE5sWTNKbGRBPT0=
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
where the value of Authorization after Basic is the Base64 encoded string based on your clientId and secret
Refer to Sabre Authentication on how this string is created
So, in order to get the access token you just need to send a POST request with required header and request parameters and you do not need to use the Authenticator