【问题标题】:$http get request always returns 401 unauthorized - doesnt send auth header$http 获取请求总是返回 401 未授权 - 不发送 auth 标头
【发布时间】:2017-07-08 08:56:30
【问题描述】:

我在 angularjs 中使用以下控制器

app.controller('download-posts-controller', function($scope, $http) {
    $http.get('http://localhost:8090/posts', {
        headers: {
            'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJQYXNjYWwiLCJ1c2VySWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.4D9TUDQAgIWAooyiMN1lV8Y5wVCrIF4rAeGzFzelSE9diqHMik9WE9x4EsNnEcxQXYATjxAZovpp-m72LpFADA'
        }
      }).success(function(response){
        window.alert(response)
    });
});

它应该只使用 GET 请求调用我的 API,在标头中发送授权令牌以验证服务器上的请求。

我收到未经授权的 401。我的 API 层启用了 CORS,所以这应该不是问题。

在浏览器检查中,我发现它似乎出于某种原因发出了一个 OPTIONS 请求,并且也没有在标头中发送身份验证令牌。

任何想法我做错了什么? 我对 angularjs 很陌生

【问题讨论】:

  • 您是否在 API 控制器中的任何位置返回 401 状态代码
  • 确保您的令牌有效
  • 是的,我确实在服务器上收到了 401,同一个令牌绝对是有效的,因为它是我用于开发的非过期令牌,我可以将它用于邮递员或我的相同请求android 应用程序(或我的网站的 apache wicket 等价物,因为我刚刚迁移到 angular),它给了我期望的响应。
  • 我可以让它发出实际的 GET 而不是不需要的 OPTIONS 请求的唯一方法是从请求中删除标头组件。然后我尝试了一个 http 拦截器来添加标头,但这也不起作用。

标签: javascript angularjs http authentication http-headers


【解决方案1】:

一定要设置凭据模式:

app.controller('download-posts-controller', function($scope, $http) {
    $http.get('http://localhost:8090/posts', {
        headers: {
            //USE credentials mode
            withCredentials: true,
            'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJQYXNjYWwiLCJ1c2VySWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.4D9TUDQAgIWAooyiMN1lV8Y5wVCrIF4rAeGzFzelSE9diqHMik9WE9x4EsNnEcxQXYATjxAZovpp-m72LpFADA'
        }
      //SUCCESS is deprecated, removed from v1.6
      //}).success(function(response){
      }).then(function(response) {
        window.alert(response)
    });
});

有关详细信息,请参阅AngularJS $http Service API Reference - Usage


这看起来很有希望,但它仍然返回 401,并且根据我的浏览器,请求中不存在标头。它总是说请求方法也是OPTIONS

来自浏览器的 OPTIONS 请求是 pre-flight request.

CORS中,发送一个带有OPTIONS方法的预检请求,这样服务器就可以响应是否可以接受发送请求。 Access-Control-Request-Method 标头作为预检请求的一部分通知服务器,当发送实际请求时,它将使用指定的请求方法发送。 Access-Control-Request-Headers 标头通知服务器在发送实际请求时,将使用指定的标头发送。然后服务器有机会确定它是否希望在这些情况下接受请求。

服务器以Access-Control-Allow-Methods 响应,它指定了查询相关资源的可行方法。

Same Origin Policy 可防止恶意网站使用用户的位置和凭据做坏事。 pre-flight requests 允许服务器允许浏览器在这些请求无害时放宽该策略。

【讨论】:

  • 这看起来很有希望,但它仍然返回 401,并且根据我的浏览器,请求中不存在标头。它总是说请求方法也是OPTIONS(即使我将url更改为stackoverflow.com - 尽管我在这里得到301)。任何想法为什么?
  • 我刚刚调试了服务器以确认标头从未包含在从角度页面发送的请求中,但我通过任何其他方法发出相同的请求并且标头已包含
【解决方案2】:

好吧,我最终发现,一个跨域(CORS)请求首先发送一个OPTIONS请求,以确保允许用户请求。 现在...我的 api 后端有一些逻辑,用于过滤所有传入的 HTTP 并检查是否存在 Authorization 标头,包括令牌(在所有情况下,除非 uri 包含'/auth/**')。当执行初始 OPTIONS 请求时,我提供的 auth 标头中的令牌不会被包含在内,因为浏览器首先等待直到 OPTIONS 回来说我可以发出此请求......因此引发异常在服务器上,因为 OPTIONS 请求未使用令牌进行验证。

修复...在这种情况下,我只是检查了“OPTIONS”HTTP 方法并忽略了身份验证。简单的。 感谢任何人帮助尝试解决这个问题。最后只需要大量的调试。

我希望这可以帮助指导至少一个遇到类似问题的其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2016-06-27
    • 2016-05-22
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    相关资源
    最近更新 更多