2013-09-26 2 views
1

Я пытаюсь использовать Restler для создания веб-api для моего нового проекта.
Одним из требований является простая аутентификация.
я нашел хороший пример на SO https://stackoverflow.com/a/7969250/965722 но это для Restler 2. Используя руководство мне удалось преобразовать этот класс Restler 3,0Restler 3.0 Базовая аутентификация

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

Мой класс образец апи выглядит так:

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

<?php 
require_once 'vendor/restler.php'; 
use Luracast\Restler\Restler; 

$r = new Restler(); 
$r->addAPIClass('Api', ''); 
$r->addAuthenticationClass('BasicAuthentication'); 
$r->handle(); 
?> 

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

Возможно, я совершу какую-то глупую ошибку, но я не могу ее найти. Это моя первая попытка базовой аутентификации, поэтому, пожалуйста, будьте добры.

Нужна ли мне специальная конфигурация на сервере?

EDIT:
Похоже, мне нужно некоторые специальные конфигурации, потому что мой сервер работает как 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

Я не знаю, почему, но мне пришлось реализовать iUseAuthentication в моем классе BasicAuthentication. (в документах ничего нет, вероятно, потому, что это 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> 

Надеется, что это помогает кто-то :)

EDIT:
Я нашел свой код, и я отправляю его здесь, может быть, кто-то найдут это полезно.

<?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 реализует iAuthenticate вместо iAuthenticate вы должны были использовать iUseAuthentication –

+0

@ZeeshanJan Я отредактировал мой ответ. Я опубликовал свой класс BasicAuthentication и образец API-класса, который реализует 'iUseAuthentication'. Все, что вам нужно сделать, это создать экземпляр Restler. Вы должны добавить '$ r-> addAuthenticationClass ('BasicAuthentication');'. Надеюсь это поможет! :) – Misiu

Смежные вопросы