我将尝试给出一个完整的方法,说明我如何使ng-token-auth与 ZF2 一起工作。首先,ng-token-auth 可以与 ruby 模块一起正常工作。因此,要使其与 ZF2 一起使用:
使用以下代码行解决 CORS 问题:
//HttpProvider
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.headers.common['Access-Control-Request-Method'] = "POST, GET, PUT, DELETE";
$httpProvider.defaults.headers.common['Origin'] = "http://xxxxxxxxxxxxxxx";
$httpProvider.defaults.headers.common['Accept'] = "application/json";
$httpProvider.defaults.headers.common['Content-Type'] = "application/json; text/html";
delete $httpProvider.defaults.headers.common['X-Requested-With'];
使用@josilber 和@sven-lauterbach回答中指出的ZFCORS 解决ZF2 上的CORS 问题
使用这些代码行格式化 ZF2 发送的响应以使其与 ng-token-auth 一起使用
$http.defaults.transformResponse = function(value, headerGetters){
var response_header = headerGetters(),
response_data = JsonHelper.IsJsonString(value) ? JSON.parse(value) : value;
if(response_data){
if(response_data.access_token)
response_header['access_token'] = response_data.access_token;
if(response_data.expires_in){
var now = new Date().getTime();
response_header['expires_in'] = now + ( parseInt(response_data.expires_in, 10) * 1000 );
}
if(response_data.token_type)
response_header['token_type'] = response_data.token_type;
if(response_data.refresh_token)
response_header['refresh_token'] = response_data.refresh_token;
if(response_data.scope)
response_header['scope'] = response_data.scope;
return response_data;
}
};
可能这不是在 AngularJS 中转换响应的最佳方法,但它解决了格式化 OAuth2 响应的问题,该问题适用于 ng-token-auth
最后,要使用 auth token 向服务器发送请求并自动刷新 token,需要更改 ng-token-auth 的一些行为。我在 AngularJS 上使用了装饰模式,通过这些代码片段解决了这个问题:
在 app.js 中
//Change behavior of oauth2 module
$provide.decorator("$auth", function($delegate, ApiAuthService){
return ApiAuthService($delegate);
});
其中ApiAuthService是由这段代码定义的工厂:
AuthProviderService.factory('ApiAuthService', ['MeService', function( MeService ){
return function($delegate){
return {
initialize: function(){ return $delegate.initialize(); },
apiUrl: function(configName){ },
retrieveData: function(key){ return $delegate.retrieveData(key); },
getConfig: function(name){ return $delegate.getConfig(name); },
getExpiry: function(){ return $delegate.getExpiry(); },
setAuthHeaders: function(h){ return $delegate.setAuthHeaders(h); },
/*persistData: function(key, val, configName){ return $delegate.persistData(key, val, configName); },
retrieveData: function(key){ return $delegate.retrieveData(key); },*/
rejectDfd: function(reason){ $delegate.rejectDfd(reason); },
invalidateTokens: function(){ return $delegate.invalidateTokens(); },
submitLogin: function(params, opts){ return $delegate.submitLogin(params, opts); },
validateUser: function(opts){
result = $delegate.validateUser(opts);
return result;
},
deleteData: function(key){
return $delegate.deleteData(key);
}
};
};
}]).config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push([
'$injector', function($injector) {
return {
request: function(req) {
$injector.invoke([
'$http', '$auth', function($http, $auth) {
var key,
_ref,
_results = [];
if (req.url.match($auth.apiUrl())) {
_ref = $auth.retrieveData('auth_headers');
//Inject value into body of request
for (key in _ref) {
//Set Authorization request header.
if(key.match('access_token')){
if(req.headers){
req.headers['Authorization'] = 'Bearer ' + _ref[key];
}else{
req.headers = {'Authorization': 'Bearer ' + _ref[key]};
}
}
if(req.headers[key]){
delete req.headers[key];
}
}
return _results;
}
}
]);
return req;
}
};
}
]);
}]);
最后我的 ng-token-auth 配置是:
//OAuth2 Module configs
$authProvider.configure([ {
"default": {
apiUrl: API_URL,
tokenValidationPath: '/me',
signOutUrl: '/oauth',
emailRegistrationPath: '/oauth',
accountUpdatePath: '/oauth',
accountDeletePath: '/oauth',
confirmationSuccessUrl: window.location.href,
passwordResetPath: '/oauth',
passwordUpdatePath: '/oauth',
passwordResetSuccessUrl: window.location.href,
emailSignInPath: '/oauth',
forceHardRedirect: true,
storage: 'localStorage',
proxyIf: function() { return false; },
proxyUrl: 'proxy',
authProviderPaths: {
github: '/auth/github',
facebook: '/auth/facebook',
google: '/auth/google'
},
tokenFormat: {
"access_token" : "{{ token }}",
"token_type" : "Bearer",
"refresh_token": "{{ clientId }}",
"expires_in" : "{{ expiry }}",
"scope" : "{{ uid }}"
},
parseExpiry: function(headers) {
var expires_in = parseInt(headers['expires_in'], 10) || null;
return expires_in;
},
handleLoginResponse: function(response) {
//Patch for persistant data as library retreive auth data from header.
return response;
},
handleAccountResponse: function(response) {
return response;
},
handleTokenValidationResponse: function(response) {
return response;
}
}
} ]);
@JerinKAlexander 我希望这些步骤能帮助您找到比我做的更好的方式来解决您的问题。