我想在从我的 API 请求资源时发送一个授权 token 。
我确实使用 $resource 实现了一个服务:
factory('Todo', ['$resource', function($resource) {
return $resource('http://localhost:port/todos.json', {port:":3001"} , {
query: {method: 'GET', isArray: true}
});
}])
我有一个存储授权 token 的服务:
factory('TokenHandler', function() {
var tokenHandler = {};
var token = "none";
tokenHandler.set = function( newToken ) {
token = newToken;
};
tokenHandler.get = function() {
return token;
};
return tokenHandler;
});
我想从 tokenHandler.get
发送 token 以及通过 Todo
服务发送的每个请求。我能够通过将其放入特定操作的调用中来发送它。例如,这有效:
Todo.query( {access_token : tokenHandler.get()} );
但我更愿意将 access_token 定义为 Todo
服务中的参数,因为它必须随每次调用一起发送。并改善DRY。
但是工厂中的所有内容都只执行一次,因此 access_token 必须在定义工厂之前可用并且之后不能更改。
有没有办法在服务中放置一个动态更新的请求参数?
最佳答案
感谢安迪·乔斯林。我选择了他包装资源操作的想法。资源的服务现在看起来像这样:
.factory('Todo', ['$resource', 'TokenHandler', function($resource, tokenHandler) {
var resource = $resource('http://localhost:port/todos/:id', {
port:":3001",
id:'@id'
}, {
update: {method: 'PUT'}
});
resource = tokenHandler.wrapActions( resource, ["query", "update"] );
return resource;
}])
如您所见,资源首先以通常的方式定义。在我的示例中,这包括一个名为 update
的自定义操作。之后,资源被 tokenHandler.wrapAction()
方法的返回值覆盖,该方法将资源和一组操作作为参数。
正如您所期望的那样,后一种方法实际上包装了操作以在每个请求中包含身份验证 token 并返回修改后的资源。那么让我们看一下它的代码:
.factory('TokenHandler', function() {
var tokenHandler = {};
var token = "none";
tokenHandler.set = function( newToken ) {
token = newToken;
};
tokenHandler.get = function() {
return token;
};
// wrap given actions of a resource to send auth token with every
// request
tokenHandler.wrapActions = function( resource, actions ) {
// copy original resource
var wrappedResource = resource;
for (var i=0; i < actions.length; i++) {
tokenWrapper( wrappedResource, actions[i] );
};
// return modified copy of resource
return wrappedResource;
};
// wraps resource action to send request with auth token
var tokenWrapper = function( resource, action ) {
// copy original action
resource['_' + action] = resource[action];
// create new action wrapping the original and sending token
resource[action] = function( data, success, error){
return resource['_' + action](
angular.extend({}, data || {}, {access_token: tokenHandler.get()}),
success,
error
);
};
};
return tokenHandler;
});
如您所见,wrapActions()
方法根据其参数创建资源副本,并循环遍历 actions
数组以调用另一个函数 tokenWrapper( )
用于每个操作。最后它返回资源的修改副本。
tokenWrapper
方法首先创建一个预先存在的资源操作的副本。此副本有尾随下划线。所以query()
变成了_query()
。之后,一个新方法覆盖了原来的 query()
方法。这个新方法包装了 _query()
,正如 Andy Joslin 所建议的那样,为通过该操作发送的每个请求提供身份验证 token 。
这种方法的好处是,我们仍然可以使用每个 angularjs 资源(获取、查询、保存等)附带的预定义操作,而无需重新定义它们。在其余代码中(例如在 Controller 中),我们可以使用默认操作名称。
关于javascript - AngularJS:如何使用 $resource 请求发送身份验证 token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11176330/