2015-02-19 2 views
21

Я создал API с использованием Apigility. Я пытаюсь установить систему аутентификации для внешнего приложения, которое я сейчас создаю с использованием API.Authenticate Angular js module для Apigility

Но все угловые модули аутентификации, которые я использовал для этой системы аутентификации не соответствие с Apigility OAuth 2 реализации:

  1. https://github.com/lynndylanhurley/ng-token-auth Проблема с этим модулем, оно не позволяет CORS. Однако он позволяет отправлять запрос CORS с использованием прокси-сервера на сервере, где расположен угловой код, который я написал на PHP с помощью Guzzle. Но с proxy ng-token-auth отправьте запрос дважды успешно, даже если все данные аутентификации являются ложными.

  2. https://github.com/sahat/satellizer Этот модуль нуждается в реализации JWT, но в разделе Apigility Authentication я не видел никакой документации по нему.

Мне нужна помощь для завершения моего проекта.

+0

@JerinKAlexander, вам нужно интегрироваться с сторонними аутентификаторами (Google, FB и т. Д.)? Вам нужен OAuth специально, или вам нужен способ аутентификации пользователей? –

+0

@JerinKAlexander, вы можете использовать ng-token-auth для решения своей цели. После некоторых чтений исходного кода ng-auth-token. У меня есть работа с Apigility. Если вас интересует мой код, я могу дать полный ответ о том, как я это понял. – hermannovich

+0

вы должны обязательно разместить свое решение. –

ответ

2

Вы можете получить satellizer для работы с Apigility с использованием довольно простого, но аккуратного обходного пути. Посмотрите здесь:

http://adam.lundrigan.ca/2014/11/06/using-oauth2-jwt-with-apigility/

и здесь:

https://github.com/adamlundrigan/LdcOAuth2CryptoToken/blob/master/src/Factory/CryptoTokenServerFactory.php

Apigility определяет сервисные заводы для всех это внутренние службы. Основная идея здесь состоит в том, чтобы просто определить фабрику делегитора сервис-менеджера, которая вводит необходимую конфигурацию.

<?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; 
    } 
} 

Все благодаря Адам Lundrigan :)

+0

Шут, ссылка затрагивает проблему криптографических токенов, которые Apigility не поддерживает. Но вы не объяснили, как запрашивать токены из конечных точек Apigility, а также как настроить Apigility для создания/отправки токенов OAuth, требовать/принимать токены OAuth. –

+0

@DaveAlperovich Извините, на мгновение я думал, что основная проблема, которую он пытается решить, заключается в том, что угловые модули аутентификации не соответствуют Apigility OAuth2. Плюс настройка apigility OAuth2 - очень простая задача, хорошо документированная в документах Apigility (https://apigility.org/documentation/auth/authentication-oauth2) – jester

+0

Чтобы быть справедливым, OP был легким в деталях, и инвестор не добавил любые детали. Мое подозрение в том, что нужно больше. Но я только догадываюсь без обратной связи. Вы можете оказаться правы. –

1

Вы хотите использовать Apigility в качестве внутреннего интерфейса. У вас есть приложение HTML, которое работает в другом домене, и это приложение HTML должно вызывать сервер Apigility с аутентификацией OAuth? Если это то, что вы пытаетесь сделать, вы должны установить Apigility для поддержки CORS вызовов, посмотрите на https://apigility.org/documentation/recipes/allowing-request-from-other-domains

Они используют модуль «ZfrCors»:

Они используют следующий образец:

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, 
), 
); 

Все, что вам нужно сделать, это установить параметр «allowed_origins» в домен вашего HTML-приложения.

Для части OAuth вы можете получить больше информации здесь: https://apigility.org/documentation/auth/authentication-oauth2

Вы должны более внимательно взглянуть на раздел «приложения на базе браузера», потому что вы используете HTML приложение, чтобы получить доступ к apigility бэкенд. С информацией, представленной в этом сообщении, вы можете использовать https://github.com/sahat/satellizer

Если вам нужна дополнительная информация, дайте мне знать.

5

Я попытаюсь дать полный метод, как я сделал 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']; 

решить проблему CORS на ZF2 с использованием ZFCORS как указано в @josilber и @ sven- Lauterbach ответ answer

Формат послан ZF2, чтобы заставить его работать с нг-маркера-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, который работает с нг-токенов-AUTH

Наконец, чтобы отправить запрос на сервер с помощью токен аутентификации и обновить токен автоматически, необходимо было изменить некоторое поведение 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; 
      } 
      }; 
     } 
     ]); 
}]); 

Наконец моя конфигурация нг-токенов-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 Я надеюсь, что эти шаги помогут вам найти способ решить свой вопрос лучше, чем то, что я сделал.

+0

Очень тщательный ... –