2015-02-19 30 views
21

Tôi đã tạo một API bằng cách sử dụng Khả năng sống. Tôi đang cố gắng đặt hệ thống xác thực cho ứng dụng giao diện người dùng mà tôi hiện đang xây dựng bằng API.Xác thực mô-đun angular js cho Tính linh hoạt

Nhưng tất cả các module xác thực góc mà tôi đã sử dụng cho hệ thống xác thực này không phù hợp với Apigility OAuth 2 thực hiện:

  1. https://github.com/lynndylanhurley/ng-token-auth Vấn đề với điều đó mô-đun được, nó không cho phép CORS. Tuy nhiên nó cho phép gửi một CORS-Request bằng cách sử dụng một proxy trên máy chủ nơi mã góc được đặt, mà tôi đã viết bằng PHP sử dụng Guzzle. Nhưng với proxy ng-token-auth gửi yêu cầu hai lần thành công ngay cả khi tất cả dữ liệu xác thực là sai.

  2. https://github.com/sahat/satellizer Mô-đun này cần triển khai JWT nhưng trong phần Xác thực khả năng xác thực, tôi chưa thấy bất kỳ tài liệu nào về nó.

Tôi cần trợ giúp để hoàn thành dự án của mình.

+0

@JerinKAlexander, bạn có cần tích hợp với trình xác thực của bên thứ ba (Google, FB, v.v ...) không? Bạn có yêu cầu OAuth cụ thể không hoặc bạn có cần một cách để xác thực người dùng không? –

+0

@JerinKAlexander, Bạn có thể sử dụng ng-token-auth để giải quyết đạt được mục tiêu của mình. Sau khi đọc một số mã nguồn của ng-auth-token. Tôi đã làm cho nó hoạt động với sự khải thị. Nếu bạn quan tâm đến mã của tôi, tôi có thể đưa ra một câu trả lời hoàn chỉnh về cách tôi đã nhận ra nó. – hermannovich

+0

bạn chắc chắn nên đăng giải pháp của mình –

Trả lời

2

Bạn thực sự có thể nhận được satellizer để làm việc với Apigility bằng cách sử dụng giải pháp thay thế đơn giản nhưng gọn gàng. Hãy xem ở đây:

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

và ở đây:

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

Apigility xác định các nhà máy phục vụ cho tất cả đó là các dịch vụ nội bộ. Ý tưởng cơ bản ở đây là chỉ cần xác định một nhà quản lý dịch vụ ủy nhiệm nhà máy mà tiêm cấu hình cần thiết.

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

Tất cả nhờ vào Adam Lundrigan :)

+0

Jester, liên kết giải quyết vấn đề mã hóa mã hóa mà Apigility không hỗ trợ. Nhưng bạn chưa giải thích cách yêu cầu mã thông báo từ các điểm kết thúc không rõ ràng, cũng như cách định cấu hình Khả năng tạo/gửi mã thông báo OAuth, yêu cầu/chấp nhận mã thông báo OAuth. –

+0

@DaveAlperovich Xin lỗi, trong một khoảnh khắc, tôi nghĩ rằng vấn đề cốt lõi mà anh đang cố gắng giải quyết là các mô-đun xác thực góc không khớp với Khả năng hoạt động OAuth2. Thêm cấu hình khả năng xác định OAuth2 là một nhiệm vụ rất đơn giản, được ghi lại rõ ràng trong tài liệu về Khả năng sống (https://apigility.org/documentation/auth/authentication-oauth2) – jester

+0

Để công bằng, OP đã sáng tỏ chi tiết và nhà đầu tư chưa thêm bất kỳ chi tiết nào. Sự nghi ngờ của tôi là cần thiết hơn. Nhưng tôi chỉ đoán mà không có phản hồi. Bạn có thể trở thành đúng. –

1

Bạn muốn sử dụng Apigility như backend. Bạn có một Ứng dụng HTML chạy trên một tên miền khác và Ứng dụng HTML này sẽ gọi cho chương trình phụ trợ Khả năng xác thực với Xác thực OAuth? Nếu đây là những gì bạn đang cố gắng để thực hiện bạn phải thiết lập Apigility để hỗ trợ CORS cuộc gọi, hãy nhìn vào https://apigility.org/documentation/recipes/allowing-request-from-other-domains

Họ sử dụng "ZfrCors" mô-đun:

Họ sử dụng các mẫu sau:

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

Tất cả những gì bạn phải làm là đặt tùy chọn 'allowed_origins' thành miền của ứng dụng HTML của bạn.

Đối với phần OAuth bạn có thể tìm thêm thông tin ở đây: https://apigility.org/documentation/auth/authentication-oauth2

Bạn nên có một cái nhìn sâu hơn về các "ứng dụng trình duyệt dựa trên" phần, bởi vì bạn sử dụng một ứng dụng HTML để truy cập apigility phụ trợ của bạn. Với thông tin được cung cấp trong bài đăng này, bạn có thể sử dụng https://github.com/sahat/satellizer

Nếu bạn cần thêm thông tin, hãy cho tôi biết.

5

Tôi sẽ cố gắng cung cấp phương pháp hoàn chỉnh về cách tôi đã thực hiện ng-token-auth hoạt động với ZF2. Chủ yếu, ng-token-auth hoạt động tốt với mô-đun ruby.Vì vậy, để làm cho nó làm việc với ZF2:

Giải quyết vấn đề CORS với những dòng mã:

//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']; 

Giải quyết vấn đề CORS trên ZF2 sử dụng ZFCORS như chỉ trong @josilber và @ sven- lauterbach phản ứng answer

Format gửi bởi ZF2 để làm cho nó làm việc với ng-token-auth sử dụng các dòng mã

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

Có thể đây không phải là cách tốt nhất để chuyển đổi phản ứng trong AngularJS nhưng nó giải quyết vấn đề của định dạng OAuth2 phản ứng mà làm việc với ng-token-auth

Cuối cùng, để gửi yêu cầu đến máy chủ sử dụng auth thẻ và tự động làm mới mã thông báo, cần phải thay đổi một số hành vi của ng-token-auth. Tôi đã sử dụng mô hình trang trí trên AngularJS để giải quyết vấn đề này với các đoạn mã:

Trong app.js

//Change behavior of oauth2 module 
$provide.decorator("$auth", function($delegate, ApiAuthService){ 
    return ApiAuthService($delegate); 
}); 

đâu ApiAuthService là một nhà máy được xác định bởi đoạn mã này:

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; 
      } 
      }; 
     } 
     ]); 
}]); 

Cuối cùng cấu hình của tôi về ng-token-auth là:

//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 Tôi hy vọng các bước này sẽ giúp bạn tìm cách giải quyết câu hỏi của mình theo cách tốt hơn so với những gì tôi đã làm.

+0

Rất kỹ lưỡng ... –

Các vấn đề liên quan