【问题标题】:AngularJS token based authentication header基于 AngularJS 令牌的身份验证标头
【发布时间】:2016-05-19 15:58:28
【问题描述】:

我对 Angular 有点陌生,并且有一个我已经启动的应用程序。这开始只是一个简单的登录,它将访问一个 REST API 并验证用户并发送回一个验证用户的 JSON 令牌。每个后续请求都会发送一个包含令牌的身份验证标头,以确保他们当然已登录。

这是我目前的代码 -

AngularJS:

;(function(){

function authInterceptor(API, auth) {
  return {
    request: function(config) {
      return config;
    }
  }
}


function authService() {

}


function userService($http, API, auth) {

    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;';
    $http.defaults.transformRequest = [function(data) {
        return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
      }];

  var self = this;

  self.login = function(username, pwd, ctrl) {
      ctrl.requestdata = API + '/winauth' + '; with ' + username;
    return $http.post(API + '/winauth', {
        username: username,
        pwd: pwd
      })
  };

  var param = function(obj) {
    var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

    for(name in obj) {
      value = obj[name];

      if(value instanceof Array) {
        for(i=0; i<value.length; ++i) {
          subValue = value[i];
          fullSubName = name + '[' + i + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value instanceof Object) {
        for(subName in value) {
          subValue = value[subName];
          fullSubName = name + '[' + subName + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value !== undefined && value !== null)
        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
    }

    return query.length ? query.substr(0, query.length - 1) : query;
  };

}


  function MainCtrl(user, auth) {
    var self = this;

    function handleRequest(res) {
      self.responsedata = res;
      self.message = res.data.message;
    }

    self.login = function() {
      this.requestdata = 'Starting request...';
      user.login(self.username, self.pwd, self)
        .then(handleRequest, handleRequest)
    }
  }

  angular.module('app', [])
  .factory('authInterceptor', authInterceptor)
  .service('user', userService)
  .service('auth', authService)
  .constant('API', 'http://development-server.com:8080/ecar/api')
  .config(function($httpProvider) {
    $httpProvider.interceptors.push('authInterceptor');
  })
  .controller('Main', MainCtrl)
  })();

现在让我说这是 不是 JWT,并且它 IS 工作。它到达服务器并在身份验证成功后(我老板的话跟随)** 发回的响应是一个 JSON 数组,其中包含一个字段名称“auth_token”,其中包含要与后续请求一起发回的令牌。该令牌必须与任何后续请求一起作为名为 X-PCC-API-TOKEN 的自定义请求标头发送。 **

这是服务器返回的响应:

    http://appsdev.pccportal.com:8080/ecar/api/winauth; with  myUsername
      {"data":{"status":"Authentication has succeeded.","auth_token":"qidn0pwcuvl4jbml73qls94hk4"},"status":200,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"url":"http://development-server.com:8080/ecar/api/winauth","data":{"username":"myUsername","pwd":"myPassword"},"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded;"}},"statusText":"OK"}

如您所见,它成功并返回一个 JSON 数组,其字段名称为“auth_token”,其中包含令牌。

我需要做的就是希望将该令牌保存到他们的本地存储中,就像我的老板对我说的那样(他是设计 API 的人)“令牌需要与每个后续请求一起发回,并且令牌必须作为名为 X-PCC-API-TOKEN 的自定义请求标头发送”

这是我正在阅读的教程中的内容:

function authService($window) {
  var self = this;

  self.parseJwt = function(token) {
    var base64Url = token.split('.')[1];
    var base64 = base64Url.replace('-', '+').replace('_', '/');
    return JSON.parse($window.atob(base64));
  }

  self.saveToken = function(token) {
    $window.localStorage['jwtToken'] = token;
  }

  self.getToken = function() {
    return $window.localStorage['jwtToken'];
  }

  self.isAuthed = function() {
    var token = self.getToken();
    if(token) {
      var params = self.parseJwt(token);
      return Math.round(new Date().getTime() / 1000) <= params.exp;
    } else {
      return false;
    }
  }

  self.logout = function() {
    $window.localStorage.removeItem('jwtToken');
  }
}

这对于拦截器:

function authInterceptor(API, auth) {
  return {

    request: function(config) {
      var token = auth.getToken();
      if(token && config.url.indexOf(API) === 0) {
        config.headers.Authorization = 'Bearer ' + token;
      }

      return config;
    }
  }

}

但这显然是针对 JWT 的。我需要它来符合我老板的指导方针,也不要使用 JWT。

很抱歉所有的代码。我希望这不是一件坏事。但是要很好地结束此身份验证并发送回一个包含令牌的 JSON 数组,我需要将其作为名为 X-PCC-API-TOKEN 的自定义标头与每个后续请求一起发送回,并希望将令牌保存到其本地存储中。

我真的需要这方面的帮助。而且真的不知道该怎么做。

谢谢

【问题讨论】:

    标签: angularjs json authentication token


    【解决方案1】:

    基本上,您的登录方法有些工作。您访问 API 服务器并获得带有令牌的响应。到现在为止还挺好。您只需将令牌保存在 localStorage 中并将其添加到每个 API 调用的 X-PCC-API-TOKEN 标头中即可。

    您可以创建另一个处理存储的服务,但如果您不想/不需要那种复杂性,您可以添加

    var authToken = res.data.auth_token;
    localStorage.setItem('token', authToken);
    

    无论您在哪里处理登录返回的数据 - 在您的情况下,它是您的 handleRequest 函数。

    之后,您只需添加拦截器。您使用 JWT 的示例非常接近您的实际需要。 (JWT 只是设置 Authorization 标头而不是您需要的标头。)

    function authInterceptor() {
        return {
            request: function (request) {
                request.headers = request.headers || {};
                request.headers['X-PCC-API-TOKEN'] = localStorage.getItem('token');
                return request;
            }
        };
    }
    

    显然,如果您使用服务来处理存储,您可以通过它获取令牌。此外,您应该只将自定义标头添加到您的 API 调用中,因此只需将其放在一个简单的 if 中,您可以在其中检查它是否为 1。

    【讨论】:

    • 使用本地存储来存储身份验证令牌时,您需要注意您的令牌可能会受到 XSS 攻击,因为它们可以通过 JavaScript 直接获取。
    • 我得到的是一个字段名为“auth_token”的 JSON 数组。这是在哪里调用的或如何将该字段名称保存在变量中..?您的响应中在哪里定义了 authToken 函数。或者我错过了什么。我对 angularJS 相当陌生,显然之前从未做过任何基于令牌的身份验证。
    • 你实际上得到了一个 JSON 对象,而不是数组。它从您的$http.post 呼叫userService 中返回。您在 MainCtrl 的登录函数 (user.login) 中调用它,并在 handleRequest 函数中处理响应。所以你应该把令牌保存在那里。我会稍微修改一下代码,请稍等。
    • @NikolajDamLarsen 是的,这是真的。但这是内部服务器上的内部应用程序,只有员工才能通过 Airwatch 应用程序在手机上安装此应用程序。
    • 甜蜜。因此,要检查它是否是 API 调用,我会在请求函数中执行类似“if (config.url.indexOf(API) === 0) { header code }”的操作吗?
    猜你喜欢
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 2021-01-25
    • 2016-01-23
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多