如何通过 AngularJS $http 从 ASP.Net Web API 2 获取访问令牌?

Posted

技术标签:

【中文标题】如何通过 AngularJS $http 从 ASP.Net Web API 2 获取访问令牌?【英文标题】:How to get Access Token from ASP.Net Web API 2 via AngularJS $http? 【发布时间】:2013-12-04 13:31:37 【问题描述】:

我尝试这样:

$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;
);

然后尝试将 grant_type 更改为参数:

$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;
);

仍然感到恐惧:"error":"unsupported_grant_type"

所以我做了 AngularJS 开发者不应该做的事,求助于 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();
;

这就像一个冠军......所以我的问题是:我们如何使用 AngularJS $http() 复制上面的 jQuery $.post() 调用,以便我们可以从 ASP 中基于 OWIN 中间件的 /token 端点获取访问令牌。网络 Web API 2?

【问题讨论】:

你的问题在这个answer解决了 【参考方案1】:

这样做:

$http(
        url: '/token',
        method: 'POST',
        data: "userName=" + $scope.username + "&password=" + $scope.password + 
              "&grant_type=password"
)

【讨论】:

请注意,键和值都没有引号。负载是不是 JSON。【参考方案2】:

我认为,将标头 headers: 'Content-Type': 'application/x-www-form-urlencoded' 添加到您的帖子请求中就可以了。应该是这样的:

$http.post(loginAPIUrl, data,
    headers:  'Content-Type': 'application/x-www-form-urlencoded' )

【讨论】:

【参考方案3】:

您收到该错误是因为 OWIN OAuth 提供程序的默认实现期望发送到“/Token”服务的帖子是表单编码的,而不是 json 编码的。这里有更详细的答案How do you set katana-project to allow token requests in json format?

但是你仍然可以使用 AngularJs,你只需要改变 $http 发布的方式。如果您不介意使用 jquery 更改您的参数,您可以在这里尝试答案 How can I post data as form data instead of a request payload? 希望对您有所帮助。

【讨论】:

+1 链接到***.com/questions/19645171/…【参考方案4】:

您始终可以在浏览器中使用开发者控制台查看正在发出的请求,并查看请求中的差异。

但是通过查看你的 jquery 代码 &grant_type=password 是在正文而不是查询字符串中传递的,所以 $http 调用应该是

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

【讨论】:

这就是我的第一个代码块的样子......我这样做了,但回来"error":"unsupported_grant_type"。我尝试将数据更改为参数,将变量放入查询字符串中,但它仍然返回该错误。 糟糕的是我没有滚动到最后。查看使用浏览器开发工具发出的请求,您就会知道不同之处,也许可以在这里使用这些细节来修复它。 是的,我在 FireBug 中四处挖掘......有一些标题差异,但我将 $http 上的标题设置为匹配,仍然是同样的错误。我想我难住了。 ;( 最后一部分grant_type:passwordpassword 需要用引号引起来【参考方案5】:

类似于 achinth,但你仍然可以使用$http.post 方法(+ 数据被转义)

$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
                     "&password=" + encodeURIComponent(password) +
                     "&grant_type=password"
).success(function (data) 
//...

【讨论】:

【参考方案6】:

1) 记下 URL:“localhost:55828/token”(不是“localhost:55828/API/token”)

2) 记下请求数据。它不是 json 格式,它只是没有双引号的纯数据。 "userName=xxx@gmail.com&password=Test123$&grant_type=password"

3) 注意内容类型。 Content-Type: 'application/x-www-form-urlencoded' (不是 Content-Type: 'application/json')

4) 当你使用javascript发出post请求时,你可以使用如下:

$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) //...

请看下面 Postman 的截图:

Postman Request

Postman Request Header

【讨论】:

以上是关于如何通过 AngularJS $http 从 ASP.Net Web API 2 获取访问令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何从AngularJS获得响应$ http.get()。then()

如何在 AngularJS 中使用 $http.get 从 jsp 页面获取响应?

AngularJS:如何通过$ http获取数据时禁用默认观察者

在 AngularJs 中从数据库中获取和显示数据

AngularJs,如何发送 $http 的参数 [重复]

如何将数据从angularjs传递给spring控制器