i have this snippet:
var req = {
method: 'POST',
url: 'https://api.dropboxapi.com/oauth2/token',
headers: {'Content-Type': 'application/json'},
data: {
'code': authCode,
'grant_type': 'authorization_code',
'client_id': 'my_id',
'client_secret': 'my_secret',
'redirect_uri':'http://localhost%3A8080/main'
}
};
return $http(req).then(function(response){
console.log(response.status);
return response;
}, function(err){
console.log(err);
});
The can always ends up in a "bad request" because ""No auth function available for given request""
The same data works with tools to send REST requests... so I don't know what I'm missing here...
Can some help?
The error message indicates that the API didn't receive the expected parameters, or at least not in a format it expected. The documentation for /1/oauth2/token say:
Calls to /oauth2/token need to be authenticated using the apps's key and secret. These can either be passed as POST parameters (see parameters below) or via HTTP basic authentication. If basic authentication is used, the app key should be provided as the username, and the app secret should be provided as the password.
You seem to be attempting to supply the parameters as JSON though, according to your Content-Type header. Try sending them as POST parameters instead.
Related
I have an account on Napster developers. And, I made an app, and I got an api key. According to Napster documents Here is what I send as a GET request over UPC.
function getByUpc() {
console.log("getByUpc is called ...");
return $http({
method: 'GET',
url: 'http://api.napster.com/v2.2/albums/upc/602498619070',
headers: {
'Authorization': 'BASIC my-apikey'
}
}).then(handleSuccess, handleError('Error getting user by id'))
}
I changed BASIC to Bearer, but I also get a same result (401 error).
Also, I tried to put apikey as a query string but I get 403 error.
Any suggestion?
http://api.napster.com/v2.2/albums/upc/602498619070?apikey=MY-APIKEY
I am trying to get access to backend written in GO which in 99% is good (problem does not lay there).
For now I just created simplest call which stay in controller (it will be in service in future) to register new user. Although I hardcoded data which I am passing the response says 403 forbidden. In powerShell shows reason of 403:
RegistrationForm parse - email: , nick:
Validation failed for email - blank
It looks like I am not passing my data correctly because email is blank. Please take a look at my code:
$ctrl.fake_registerSubmit = function() {
$http({
url: 'http://localhost:3000/v1/sign_up',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
data: {
email: 'check#onet.pl',
nick: 'borysxoxo',
password: 'admin12312',
password_confirmation: 'admin12312'
}
})
.then(function successCall(response, post) {
console.log('user added');
}, function errorCall(respone) {
console.log('error callback');
console.log(respone);
})
};
This screenshot presents API documentation which I am trying to access:
link
What am I doing wrong? Is there other way to pass data?
You are sending some json data with the wrong Content-Type.
I see 2 options, either change Content-Type in your header to:
'Content-type' : 'application/json'
or transform your payload to:
data: "email=check#onet.pl&nick=borysxoxo&password=admin12312&password_confirmation=admin12312"
Preface: I am using AngularJS 1.5.9.
When writing my service, this code works when posting to the server:
var request = {
url: '/connect/token',
method: 'POST',
data: $httpParamSerializer(params),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
$http(request).then(function(response) {});
However, it seems counterintuitive to use data when $http has the usage argument params, with the following definition as per AngularJS's documentation:
params – {Object.} – Map of strings or objects which
will be serialized with the paramSerializer and appended as GET
parameters.
As you can see, the documentation specifies that this argument is meant to be used only for GET requests. I confirmed as much when I attempted to use the params argument with my POST request:
var request = {
url: '/connect/token',
method: 'POST',
params: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
$http(request).then(function(response) {});
When you submit the POST request in this way, you get the following response from the server:
{
"error":"invalid_request",
"error_description":"A malformed token request has been received: the mandatory 'Content-Type' header was missing from the POST request."
}
In other words, if I don't use the data argument and invoke the param serializer service on the params I want to pass in, my custom service won't set the Content-Type header on my request, I've confirmed this in the network tab of the web inspector.
TLDR; Why do I have to use the data argument and serialize the params instead of just using the params argument directly? And why is the content type I specify ignored when I do use the params argument?
Use params option for GET requests.
With params option you can set URL query string parameters like baseurl.com?myParam=something
I'm using angularjs and I'm trying to make a HttpPost call to my web api.
My api method:
[HttpPost]
[Route("authentication/getkey")]
public IHttpActionResult GetKey([FromBody]string password) {
//Do stuff
}
my call:
service.getKey = function (password) {
return $http.post('api/authentication/getkey', JSON.stringify(password))
.then(function(result) {
return result.data;
});
}
Now this works fine, but do I really need to use JSON.stringify? I tried sending it like below, but all of them get password = null. Do I have to use JSON.stringify or am I doing it wrong in my other examples?
//Doesnt work
service.getKey = function (password) {
return $http.post('api/authentication/getkey', password)
.then(function(result) {
return result.data;
});
}
//Doesnt work
service.getKey = function (password) {
return $http.post('api/authentication/getkey', {password})
.then(function(result) {
return result.data;
});
}
If you don't want to use JSON.stringify, the other option will be to send the data as application/x-www-form-urlencoded as pointed in other answer as well. This way you are sending the data as form data. I'm not sure about the syntax of the $http.post Shortcut method but the idea is the same.
service.getKey = function (password) {
$http({
method: 'POST',
url: 'api/authentication/getkey',
data: $.param({ '': password }),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function(result) {
return result.data;
});
From Microsoft's Web API official documentation about Parameter Binding in ASP.NET Web API:
When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).
Angular $http service sends Content-Type: application/json as header by default in POST requests, as you can see from the official docs, so Web API is trying to bind your request body using his JsonFormatter. Because of this you have to provide him a well formatted Json string (not a Json Object with a string inside) to correctly bind his raw string parameter.
As a side note, you could also send a request using application/x-www-form-urlencoded as Content-Type header, but then you will have to format your body as form parameters (using something similar to jQuery $.param( .. ))
My REST backend [ based on NodeJS/express/mongojs] is complaining 404 (not found) when Params are attached as part of URL. Backend rest interface is coded as below;
var express = require('express');
var router = express.Router();
router.get('/login', auth.signin); //auth.signin is code to verify user
Above REST service is consumed by AngularJS based frontend through $resource as below;
Definition:
angular.module('myapp').factory('signinmgr', function($resource) {
return $resource("http://localhost:3000/login", {}, {
'get': {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}});
Usage:
signinmgr.get({'username':'myname', 'password':'mypass'}, function(data){
//success
}, function(x){
//failed
});
Problem:
Frontend code above produces a URL to consume REST service where parameters are part of URL i.e. http://localhost:port/login?username=myname&password=mypass [if I use GET method, POST is OK]. I wanted my front end to keep URL as http://localhost:port/login and post any parameters through body as backend is using req.body.paramName to read those. [Actual Solution]
If (1) cannot be done, and my frontend is sending params as part of URL, I needed help as to know how to equip my backend to allow this URL with parameters so that backend doesnt return 404 as the base URL http://localhost:port/login is already there.
PS: for (1), I tried this thread with data:{username:'',password:''} but of no use. Please help if I am missing something very obvious or some concept.
Try the $http service instead:
angular.module('myapp').factor('signinmgr', function($http) {
return {
login: function (username, password) {
$http.post("http://localhost:3000/login", {
username: username,
password: password
}
}
};
});
signinmgr.login('myname', 'mypass').then(function(data){
//success
}, function(x){
//failed
});
Each request that my nodejs/expressjs backend receives has three places for passed attributes;
params{}
query{}
body{}
My problem (1) cannot be fixed in case I want to use GET method since with GET request parameters are visible as part of URL i.e. http://localhost:port/login?username=myname&password=mypass. To send my username/password I had to use POST that sends parameters as part of body{}.
My problem (2) was that I was using GET and mistakenly looking for parameters in body{} of request. Instead, parameters passed as part of URL in GET request are added to query{} of the request.