20

I try like this:

$http({ method: 'POST', url: '/token', data: { username: $scope.username, password: $scope.password, grant_type: 'password' } }).success(function (data, status, headers, config) {
    $scope.output = data;
}).error(function (data, status, headers, config) {
    $scope.output = data;
});

then tried changing the grant_type to a param:

$http({ method: 'POST', url: '/token', data: { username: $scope.username, password: $scope.password }, params: { grant_type: 'password' } }).success(function (data, status, headers, config) {
    $scope.output = data;
}).error(function (data, status, headers, config) {
    $scope.output = data;
});

Still get the dreaded: {"error":"unsupported_grant_type"}

So I do what no AngularJS developer should ever do, resorted to jQuery:

var data = $('#regForm').serialize() + "&grant_type=password";
$.post('/token', data).always(showResponse);

function showResponse(object) {
    $scope.output = JSON.stringify(object, null, 4);
    $scope.$apply();
};

Which works like a champ... so my question is: how do we replicate the jQuery $.post() call above using AngularJS $http() so we can grab an access token from the OWIN middleware based /token endpoint in ASP.Net Web API 2?

Chaddeus
  • 13,134
  • 29
  • 104
  • 162

6 Answers6

19

Do this:

$http({
        url: '/token',
        method: 'POST',
        data: "userName=" + $scope.username + "&password=" + $scope.password + 
              "&grant_type=password"
})
Achinth Gurkhi
  • 2,136
  • 4
  • 24
  • 45
18

I think, adding the header {headers: { 'Content-Type': 'application/x-www-form-urlencoded' } to your post request would do the trick. It should be something like this:

$http.post(loginAPIUrl, data,
    {headers: { 'Content-Type': 'application/x-www-form-urlencoded' }})
zafeiris.m
  • 4,339
  • 5
  • 28
  • 41
6

You are getting that error because the default implementation of the OWIN OAuth provider is expecting the post to the "/Token" service to be form encoded and not json encoded. There is a more detailed answer here How do you set katana-project to allow token requests in json format?

But you can still use AngularJs you just have to change the way the $http post is made. You can try the answer here if you don't mind using jquery to change your params How can I post data as form data instead of a request payload? Hope that helps.

Community
  • 1
  • 1
Kent Cooper
  • 4,319
  • 3
  • 19
  • 23
  • +1 for link to http://stackoverflow.com/questions/19645171/how-do-you-set-katana-project-to-allow-token-requests-in-json-format – David Peden Sep 28 '14 at 05:20
2

You can always watch for the requests being made using the developer console in your browser and see the difference in the request.

But by looking at your jquery code &grant_type=password is being passed in the body not the querystring so the $http call should be

$http({ method: 'POST', url: '/token', data: { username: $scope.username, password: $scope.password ,grant_type:password} }).success(function (data, status, headers, config) {

Chandermani
  • 42,589
  • 12
  • 85
  • 88
  • That's what my first block of code looks like... I do that, but get back `{"error":"unsupported_grant_type"}`. I tried changing data to params, which put the variables into the querystring, but it still returns that error. – Chaddeus Dec 04 '13 at 15:25
  • My bad i did not scroll to the end. Look at the request made using the browser dev tools and you would know the different, and maybe that details can be used here to fix it. – Chandermani Dec 04 '13 at 15:30
  • Yea, I was digging around in FireBug... there were a couple header differences, but I set the headers on `$http` to match, still same error. I think I'm stumped. ;( – Chaddeus Dec 04 '13 at 15:39
  • That last part `grant_type:password`, the `password` needs to be in quotes – Serj Sagan Mar 24 '15 at 08:36
1

Similar to achinth, but you can still use the $http.post method (+ data is escaped)

$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
                     "&password=" + encodeURIComponent(password) +
                     "&grant_type=password"
).success(function (data) {
//...
Serj Sagan
  • 28,927
  • 17
  • 154
  • 183
0

1) Note the URL: "localhost:55828/token" (not "localhost:55828/API/token")

2) Note the request data. Its not in json format, its just plain data without double quotes. "userName=xxx@gmail.com&password=Test123$&grant_type=password"

3) Note the content type. Content-Type: 'application/x-www-form-urlencoded' (not Content-Type: 'application/json')

4) When you use javascript to make post request, you may use following:

$http.post("localhost:55828/token", 
    "userName=" + encodeURIComponent(email) +
        "&password=" + encodeURIComponent(password) +
        "&grant_type=password",
    {headers: { 'Content-Type': 'application/x-www-form-urlencoded' }}
).success(function (data) {//...

See screenshots below from Postman:

Postman Request

Postman Request Header

Chirag
  • 1,683
  • 2
  • 17
  • 26