在调用REST端点之前进行身份验证
Authenticate before calling REST endpoint
我试图在调用任何其他端点之前从我的REST API获得身份验证令牌(最好是一次)。为此,我创建了一个令牌工厂,它调用登录并接收回令牌。然后,我希望将该令牌工厂注入到其他控制器中。我希望依赖关系得到尊重,但我的控制器在从令牌工厂获得令牌之前调用服务。我做错了什么?
工厂:app.factory('tokenFactory', function($http, appConfig) {
console.log('calling endpoint: ' + appConfig.REST_ENDPOINT + 'authentication/login');
var apiToken;
$http.post(appConfig.REST_ENDPOINT + 'authentication/login', {
"username": "john",
"password": "open$esame"
}).
success(function(data) {
apiToken = data.token;
}).
error(function(data) {
//
});
return {
apiToken: apiToken
};
});
控制器:
app.controller('clientListCtrl', function($scope, $http, appConfig, tokenFactory) {
console.log('calling endpoint: ' + appConfig.REST_ENDPOINT+'/client/list');
$http.get(appConfig.REST_ENDPOINT+'/client/list', {
header: { 'Authorization': tokenFactory.apiToken }
})
.success(function(data) {
$scope.clients = data;
}).
error(function(data, status) {
//
});
});
是的,您必须考虑Ajax的异步方面并利用承诺链接($http.post
实际上返回您需要返回的承诺)。工厂将使用getToken
方法,可以定义一个success
方法,在收到结果时通知。
app.factory('tokenFactory', function($http, appConfig) {
console.log('calling endpoint: ' + appConfig.REST_ENDPOINT + 'authentication/login');
return {
getToken: function() {
return $http.post(appConfig.REST_ENDPOINT + 'authentication/login', {
"username": "john",
"password": "open$esame"
}).
success(function(data) {
return data.token;
}).
error(function(data) {
//
});
}
};
});
也就是说,我认为你应该利用Angular的HTTP拦截器特性。这允许在请求中透明地设置安全令牌。第一次使用AJAX获得令牌,然后您可以重用这个令牌。
app.factory('securityTokenInterceptor', function($q, tokenFactory) {
var currentToken = null;
return {
request: function(config) {
if (currentToken != null) {
config.headers['Authorization'] = currentToken;
return config;
}
var deferred = $q.defer();
tokenFactory.getToken().then(function(token) {
config.headers['Authorization'] = token.token;
currentToken = token.token;
deferred.resolve(config);
}, function(err) {
// Handle error (reject promise, ...)
});
return deferred.promise;
}
};
})
以下是在$httpProvider
上注册拦截器的方法:
app.config(function($httpProvider) {
$httpProvider.interceptors.push('securityTokenInterceptor');
})
这是我用来获取令牌的假工厂:
app.factory('tokenFactory', function($q, $timeout) {
return {
getToken: function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve({token:'mytoken'});
}, 500);
return deferred.promise;
}
};
})
希望它能帮助你,蒂埃里
在你工厂:$http.post()
是异步的,因此它之后的返回将不包含来自post请求的数据。我建议返回调用$http.post()
获得的promise对象。
在你的控制器:你可以使用返回的promise并定义成功方法,在这个方法中你可以执行get请求。
tokenFactory.success(function (tokenData) {
token = tokenData.token;
$http.get(endpoint, { header: { 'auth': token } })
.success(...)
.error(...);
});
我不确定这是不是最好的方法,但我认为可以这样做。
相关文章:
- Passport.js成功的身份验证根本没有调用
- 使用 feathersjs 通过简单的 rest 调用进行身份验证
- 如何使用 Javascript 对 SharePoint REST 调用进行身份验证
- 保留 Azure 移动服务的自定义 API 调用的用户身份验证
- 不调用的 Passportjs 是身份验证
- Google Plus api 调用未经身份验证
- 如何使用基本身份验证从 angularjs 调用 rest 服务
- Azure Table Storage 通过 javascript 对 REST 调用进行身份验证
- 护照.js身份验证成功,未调用 next()
- 如何使用 JavaScript 调用 HTTPS 身份验证
- 使用HTTP基本身份验证的JQuery Ajax调用
- 对passportjs+Node.js+Express.js Rest API调用成功身份验证和失败的路由处理程序
- 身份验证-$http'调用了s.then()成功回调,而不是错误回调
- 推送器:“;未捕获的类型错误:无法调用方法'scopedTo'未定义的“;进行身份验证时
- 在MVC控制器和JavaScript Ajax调用之间需要身份验证
- 使用activedirectory身份验证在JavaScript中调用Azure API应用程序
- 在调用REST端点之前进行身份验证
- 对服务帐户进行身份验证,以便使用JavaScript客户端库调用Google API
- 为使用Azure Active Directory身份验证保护的Web API的AJAX调用添加身份验证令牌
- 对Twitter API进行身份验证调用,以避免速率限制