Аутентификация пользователя REST - PullRequest
4 голосов
/ 21 сентября 2009

ОК ... основная идея - физически разделить СЕРВЕРА и КЛИЕНТА (две системы).

Моя идея - создать автономный веб-сервис (REST, XML, API-KEY), который обеспечит

  1. Аутентификация: логин пользователя, выход из системы
  2. Данные: Получить список продуктов

Затем я буду создавать клиентов на разных языках (Flash, PHP, JavaScript). Данные будут обслуживаться только аутентифицированным пользователям.

Типичное сообщение для пользователя для получения списка продуктов:

  1. (1 запрос) Войти / начать сеанс
  2. (1 запрос) Получить список продуктов
  3. (1 запрос) Получить список продуктов
  4. ...

ОК ... Теперь у меня проблема с пользовательским сеансом. Скажем, мы хотим построить клиент Javascript, нам нужно создать клиент PHP, который будет взаимодействовать с REST (PHP знает о REST API-KEY) и будет перенаправлять информацию в Javascript (КЛИЕНТ), верно? Пользователь войдет через PHP на REST сервер и затем запросит данные через PHP на REST сервер?

Вопросы:

  • Теперь, как PHP хранит информацию об открытом сеансе пользователя на REST-сервере?
  • Если моя идея плохая, каков правильный способ реализации?
  • Альтернативы

Ответы [ 5 ]

7 голосов
/ 22 сентября 2009

Интерфейс RESTful не хранит никакой информации о сеансе конкретного пользователя. Работа клиента состоит в том, чтобы поддерживать информацию о том, что он делает.

Аутентифицируйте пользователя по каждому запросу, предоставив информацию в HTTP-заголовке авторизации. ЕСЛИ это становится проблемой производительности, тогда посмотрите на альтернативные решения для оптимизации производительности.

4 голосов
/ 21 сентября 2009

К первому вопросу: запросы XmlHttpRequest к сервису все равно будут передавать куки, которые можно использовать для распространения идентификатора сеанса. Вы даже можете (при условии, что браузер конечного пользователя поддерживает его) пометить файлы cookie как «HttpOnly», чтобы уменьшить объем занимаемой ими XSS-зоны. См. статью Джеффа Этвуда , чтобы узнать об этом подробнее.

1 голос
/ 21 сентября 2009

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

0 голосов
/ 14 сентября 2011

Я столкнулся с той же проблемой. Я использовал restserver в php. Конечно, трафик проходит через SSL-соединение.

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

Аналогичный пост: Аутентификация RESTful Хороший ресурс также OAuth2 . Также Google использует oauth:

OAuth 2.0 - это новый упрощенный протокол авторизации для всех API Google. Для обеспечения безопасности OAuth 2.0 использует SSL, а не требует, чтобы ваше приложение выполняло криптографическую подпись напрямую Этот протокол позволяет вашему приложению запрашивать доступ к данным, связанным с учетной записью Google пользователя.

Когда приложение использует это: http://restserver/user/login и скажем, что аутентификация прошла нормально, само приложение создает сессию следующим образом:

Отдых клиента / Приложение

    public function login() {

    .... form_validation

    // get restserver salt so we can send hashed password
    $message = $this->rest->get('https://restserver/user/salt');

    if($message['status_code'] !== '0') 
      exit;       

    $data = array(
      'username'  => $this->input->post('username'),
      'password'   => prepare_password_salt($this->input->post('password'), $message['salt'])
    );      

    // authenticate with restserver, check if the user and password exist
    $msg = $this->rest->post('https://restserver/user/login', $data);

    if($msg['status_code'] === '0')
    {
      // make session
      $session_data = array(
        'logged_in'     => true,
        'username'    =>  $data['username']
      );

      $this->session->set_userdata($session_data);
      redirect(base_url() . 'some_page');

Сервер отдыха

/**
 * http://restserver/user POST 
 * - insert new user
 *
 * http://restserver/user/id PUT
 * - update existing user
 * 
 * http://restserver/user/login POST
 * - check if username exists and the password match
 * 
 * - return true on success login
 * - return false on failure
 *
 * http://restserver/user/id/hashed_pass GET
 * again client gets salt and then send hashed_pass
 * - return array(
 *   'username' ..
 *   'email' .... 
 *   .. other information
 * );
 * or we could use some access token but that means that the restserver
 * must save token for each user for some time and then delete
 *
 * HTTP server Allowed methods: GET, POST, PUT
 * HTTP server disallowed methods: DELETE
**/

class User extends Rest_Controller
{
  public function __construct()
  {
    parent::__construct();
    $this->load->library('form_validation');
  }

  /**
   * Check username and password with database.
   * 
   * @link /
   * @param $_POST['username'] (string)
   * @param $_POST['password'] (string - sha1(password . salt)) 
   * @return array which contains
   *                array['status_code']
   *                array['status']               
   *                status_code 0 means that login was successful
   *                status_code 1 means that username or password is incorrect
   */
   public function login_post()
   {
     $this->load->model('User_Model', 'user_model');

     $this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[3]|max_length[64]');
     $this->form_validation->set_rules('password', 'Password', 'trim|required|exact_length[40]');

     if($this->form_validation->run() === true)
     {
       // check with the database
       if($this->user_model->authenticate($this->input->post('username'), $this->input->post('password')))
       {
         // update user last_login field
         $this->user_model->updateLogin($this->input->post('username'));

         $message = array(
           'status_code'    => '0',
           'status'     => 'Login ok.'
         );     
       }
       else
       {
         $message = array(
           'status_code'    => '1',
           'status'     => 'Username or password is incorrect.'
         );
       }
     }
     $this->response($message, 200);
   }
0 голосов
/ 21 сентября 2009

Вам не нужен PHP для хранения API-ключа, если вы делаете свои клиентские классы в javascript достаточно умными, чтобы добавлять API-ключ (загружаемый при входе в систему) в заголовки каждого XmlHttpRequest, который будет порождать ваш класс.

Также было бы полезно отметить, что API-KEY не обязательно означает ключ аутентификации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...