2013-09-26 2 views
1

나는 내 새 프로젝트를위한 웹 API를 만들기 위해 Restler를 시험 중이다.
요구 사항 중 하나는 간단한 인증입니다.
나는 SO https://stackoverflow.com/a/7969250/965722에 좋은 예를 발견하지만 내가 3.0Restler 3.0 Basic 인증

<?php 
class BasicAuthentication implements iAuthenticate 
{ 
    const REALM = 'Restricted API'; 
    public static $currentUser; 
    public static $requires = 'user'; 
    public static $role = 'user'; 

    public function __isAllowed() 
    { 
     if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) 
     { 
      $user = $_SERVER['PHP_AUTH_USER']; 
      $pass = $_SERVER['PHP_AUTH_PW']; 
      $user = mysql_real_escape_string($user); 
      $pass = mysql_real_escape_string($pass); 

      $roles = array('12345' => 'user', '67890' => 'admin'); 

      if (!isset($pass) || !array_key_exists($pass, $roles)) 
      { 
       return false; 
      } 

      static ::$role = $roles[$pass]; 
      Resources::$accessControlFunction = 'AccessControl::verifyAccess'; 
      return static ::$requires == static ::$role || static ::$role == 'admin'; 
     } 
     header('WWW-Authenticate: Basic realm="' . self::REALM . '"'); 
     throw new RestException(401, 'Basic Authentication Required'); 
    } 

    /** 
    * @access private 
    */ 
    public static function verifyAccess(array $m) 
    { 
     $requires = isset($m['class']['AccessControl']['properties']['requires']) ? $m['class']['AccessControl']['properties']['requires'] : false; 
     return $requires ? static ::$role == 'admin' || static ::$role == $requires : true; 
    } 
} 
?> 

내 샘플 API 클래스가 너무 좋아 보인다 Restler 해당 클래스를 변환하는 관리 매뉴얼을 사용하여 Restler 2. 위한거야 :

<?php 
class Api 
{ 
    /** 
    * @url GET 
    * @url GET hello 
    * @url GET hello/{to} 
    */ 
    function hello($to = 'world') 
    { 
     return "Hello $to!"; 
    } 
    /** 
    * @access protected 
    * @class AccessControl {@requires user} 
    */ 
    public function user() 
    { 
     return "protected api, only user and admin can access"; 
    } 
    /** 
    * @access protected 
    * @class AccessControl {@requires admin} 
    */ 
    public function admin() 
    { 
     return "protected api, only admin can access"; 
    } 
} 

하나를 내 index.php

내 웹 페이지 표준 로그인 및 비밀번호 형식으로 이동해도 올바른 사용자 이름과 암호를 입력해도 아무 일도 일어나지 않습니다. 로그인 창이 다시 열립니다.

나는 어리석은 실수를하고 있을지 모르지만 나는 그것을 찾을 수 없다. 이것이 기본 인증에 대한 첫 번째 시도이므로 친절하시기 바랍니다.

서버에 특별한 구성이 필요합니까?

편집 : 내 서버가 CGI/FastCGI를로 실행되기 때문에 내가 어떤 특별한 설정이 필요한 것처럼
것 같습니다.
이 주석의 코드를 추가하려고 시도했습니다 : http://php.net/manual/en/features.http-auth.php#106285 .htaccess를 올바르게 구성 할 수 없습니다. 이것은 기본 Restler의 htaccess로 파일입니다
:

Options -MultiViews 
DirectoryIndex index.php 
<IfModule mod_rewrite.c> 
    RewriteEngine On 
    RewriteRule ^$ index.php [QSA,L] 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule ^(.*)$ index.php [QSA,L] 
</IfModule> 
<IfModule mod_php5.c> 
    php_flag display_errors Off 
</IfModule> 

이러한 라인이 일을 이전 링크에서 해결에 필요한는 :

RewriteEngine on 
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last] 

방법을 모두 결합?

답변

2

왜 그런지 모르겠지만 BasicAuthentication 클래스에 iUseAuthentication을 구현해야했습니다. (이것에 관해서는 문서에 아무것도 없다. 왜냐하면 이것이 RC 릴리스이고 문서와 샘플이 수정 되었기 때문일 것이다).
이렇게하면 모든 것이 작동하기 시작합니다.
또한 나는과 같이 htaccess로 수정 :

Options -MultiViews 
DirectoryIndex index.php 
<IfModule mod_rewrite.c> 
    RewriteEngine On 
    RewriteRule ^$ index.php [QSA,L] 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule ^(.*)$ index.php [QSA,L] 
    RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last] 
</IfModule> 
<IfModule mod_php5.c> 
    php_flag display_errors Off 
</IfModule> 

희망이 누군가 :)

편집하는 데 도움이 :
내 코드를 발견했습니다 내가 여기를 게시하도록하겠습니다, 어쩌면 누군가가 발견 할 것이다 유용합니다.

<?php 
use \Luracast\Restler\iAuthenticate; 
use \Luracast\Restler\Resources; 
class BasicAuthentication implements iAuthenticate 
{ 
    const REALM = 'Restricted API'; 
    public static $requires = 'user'; 
    public static $role = 'user'; 

    public function __isAllowed() 
    { 
     //set http auth headers for apache+php-cgi work around 
     if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)) 
     { 
      list($name, $password) = explode(':', base64_decode($matches[1])); 
      $_SERVER['PHP_AUTH_USER'] = strip_tags($name); 
      $_SERVER['PHP_AUTH_PW'] = strip_tags($password); 
     } 

     //set http auth headers for apache+php-cgi work around if variable gets renamed by apache 
     if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches)) 
     { 
      list($name, $password) = explode(':', base64_decode($matches[1])); 
      $_SERVER['PHP_AUTH_USER'] = strip_tags($name); 
      $_SERVER['PHP_AUTH_PW'] = strip_tags($password); 
     } 
     if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) 
     { 
      $user = $_SERVER['PHP_AUTH_USER']; 
      $pass = $_SERVER['PHP_AUTH_PW']; 

      $roles = array('12345' => 'user', '67890' => 'admin'); 

      if (!isset($pass) || !array_key_exists($pass, $roles)) 
      { 
       return false; 
      } 

      static ::$role = $roles[$pass]; 
      Resources::$accessControlFunction = 'BasicAuthentication::verifyAccess'; 
      $x = static ::$requires == static ::$role || static ::$role == 'admin'; 

         $file = 'a.txt'; 
      $current = file_get_contents($file); 
      $current .= static ::$requires." ".static::$role . "\n"; 
      file_put_contents($file, $current); 

      return $x; 
     } 
     header('WWW-Authenticate: Basic realm="' . self::REALM . '"'); 
     throw new RestException(401, 'Basic Authentication Required'); 
    } 

    /** 
    * @access private 
    */ 
    public static function verifyAccess(array $m) 
    { 
     $requires = isset($m['class']['BasicAuthentication']['properties']['requires']) ? $m['class']['BasicAuthentication']['properties']['requires'] : false; 

           $file = 'a.txt'; 
      $current = file_get_contents($file); 
      $current .= $requires." - ".static::$role . "\n"; 
      file_put_contents($file, $current); 
     return $requires ? static ::$role == 'admin' || static ::$role == $requires : true; 
    } 
} 
?> 

내 샘플 API 클래스 :

<?php 
class Api implements iUseAuthentication 
{ 
    private $_authenticated = false; 
    /** 
    * This method will be called first for filter classes and api classes so 
    * that they can respond accordingly for filer method call and api method 
    * calls 
    * 
    * 
    * @param bool $isAuthenticated passes true when the authentication is 
    *        done, false otherwise 
    * 
    * @return mixed 
    */ 
    public function __setAuthenticationStatus($isAuthenticated = false) 
    { 
     $this->_authenticated = $isAuthenticated; 
    } 

    /** 
    * @access protected 
    * @class BasicAuthentication {@requires user} 
    */ 
    public function user() 
    { 
     return "protected api, only user and admin can access"; 
    } 
    /** 
    * @access protected 
    * @class BasicAuthentication {@requires admin} 
    */ 
    public function admin() 
    { 
     return "protected api, only admin can access"; 
    } 
} 
?> 
+0

@Misiiu 당신이 줄을 의미합니까 : 클래스 BasicAuthentication 선택은 당신이 내 대답을 편집 한 @ZeeshanJan iUseAuthentication –

+0

를 사용했다 대신 IAuthenticate를의 IAuthenticate를 구현합니다. 나는 BasicAuthentication 클래스와'iUseAuthentication'을 구현하는 샘플 API 클래스를 게시했습니다. Restler 인스턴스를 만들 때해야 할 일 모두'$ r-> addAuthenticationClass ('BasicAuthentication');'을 추가해야합니다. 희망이 도움이! :) – Misiu