angularjs - Autentica el módulo Angular js para Apigility
authentication oauth-2.0 (3)
Desea utilizar Apigility como back-end. ¿Tiene una aplicación HTML que se ejecuta en un dominio diferente y esta aplicación HTML debe llamar al servidor de Apigility con autenticación OAuth? Si esto es lo que está tratando de lograr, debe configurar Apigility para que admita las llamadas CORS, eche un vistazo a https://apigility.org/documentation/recipes/allowing-request-from-other-domains
Usan el módulo "ZfrCors":
Usan la siguiente muestra:
return array(
''zfr_cors'' => array(
/**
* Set the list of allowed origins domain with protocol.
*/
''allowed_origins'' => array(''http://www.sexywidgets.com''),
/**
* Set the list of HTTP verbs.
*/
''allowed_methods'' => array(''GET'', ''OPTIONS''),
/**
* Set the list of headers. This is returned in the preflight request to indicate
* which HTTP headers can be used when making the actual request
*/
''allowed_headers'' => array(''Authorization'', ''Content-Type''),
/**
* Set the max age of the preflight request in seconds. A non-zero max age means
* that the preflight will be cached during this amount of time
*/
// ''max_age'' => 120,
/**
* Set the list of exposed headers. This is a whitelist that authorize the browser
* to access to some headers using the getResponseHeader() JavaScript method. Please
* note that this feature is buggy and some browsers do not implement it correctly
*/
// ''exposed_headers'' => array(),
/**
* Standard CORS requests do not send or set any cookies by default. For this to work,
* the client must set the XMLHttpRequest''s "withCredentials" property to "true". For
* this to work, you must set this option to true so that the server can serve
* the proper response header.
*/
// ''allowed_credentials'' => false,
),
);
Todo lo que tiene que hacer es establecer la opción ''allowed_origins'' en el dominio de su aplicación HTML.
Para la parte OAuth puede obtener más información aquí: apigility.org/documentation/auth/authentication-oauth2
Deberías echar un vistazo más de cerca a la sección "Aplicaciones basadas en navegador", porque usas una aplicación HTML para acceder a tu servidor de apigilidad. Con la información proporcionada en esta publicación, puede usar https://github.com/sahat/satellizer
Si necesita más información, hágamelo saber.
Creé una API usando Apigility. Estoy tratando de establecer el sistema de autenticación para una aplicación de front-end que estoy construyendo usando la API.
Pero todos los módulos de autenticación angular que he utilizado para este sistema de autenticación no se corresponden con la implementación de Apigility oAuth 2:
https://github.com/lynndylanhurley/ng-token-auth El problema con ese módulo es que no permite CORS. Sin embargo, permite enviar una CORS-Request utilizando un proxy en el servidor donde se encuentra el código angular, que he escrito en PHP usando Guzzle. Pero con proxy ng-token-auth, enviar una solicitud tiene éxito dos veces, incluso si todos los datos de autenticación son falsos.
https://github.com/sahat/satellizer Este módulo necesita implementación de JWT, pero en la sección Autenticación de apigility no he visto ninguna documentación sobre él.
Necesito ayuda para finalizar mi proyecto.
En realidad, puede hacer que el satellizer
funcione con Apigility
usando una solución bastante simple pero ordenada. Eche un vistazo aquí:
http://adam.lundrigan.ca/2014/11/06/using-oauth2-jwt-with-apigility/
y aquí:
Apigility define las fábricas de servicios para todos sus servicios internos. La idea básica aquí es simplemente definir una fábrica de delegado de administrador de servicio que inyecte la configuración necesaria.
<?php
namespace LdcOAuth2CryptoToken/Factory;
use Zend/ServiceManager/DelegatorFactoryInterface;
use Zend/ServiceManager/ServiceLocatorInterface;
class CryptoTokenServerFactory implements DelegatorFactoryInterface
{
public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback)
{
$server = call_user_func($callback);
// do your thing to $server here
return $server;
}
}
Todo gracias a Adam Lundrigan :)
Trataré de dar un método completo de cómo he hecho que https://github.com/lynndylanhurley/ng-token-auth funcione con ZF2. En primer lugar, ng-token-auth funciona bien con el módulo ruby. Para que funcione con ZF2:
Resuelva el problema CORS con estas líneas de código:
//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''];
Resuelva el problema de CORS en ZF2 usando ZFCORS como se indica en @josilber y @ sven-lauterbach answer
Respuesta de formato enviada por ZF2 para que funcione con ng-token-auth usando estas líneas de códigos
$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;
}
};
Puede ser que esta no sea la mejor forma de transformar la respuesta en AngularJS, pero resuelve el problema de formatear la respuesta de OAuth2 que funciona con ng-token-auth
Finalmente, para enviar una solicitud al servidor usando auth token y actualizar el token automáticamente, fue necesario cambiar el comportamiento de ng-token-auth. He usado el patrón de decorar en AngularJS para resolver este problema con estos fragmentos de código:
En app.js
//Change behavior of oauth2 module
$provide.decorator("$auth", function($delegate, ApiAuthService){
return ApiAuthService($delegate);
});
Donde ApiAuthService es una fábrica definida por este fragmento de código:
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;
}
};
}
]);
}]);
Por último, mi configuración de ng-token-auth fue:
//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 Espero que estos pasos te ayuden a encontrar tu camino para resolver tu pregunta de una mejor manera que lo que he hecho.