REST用户身份验证

时间:2009-09-21 09:10:56

标签: php javascript authentication rest

好的......基本的想法是让SERVER和CLIENT在物理上分开(两个系统)。

我的想法是构建一个将提供的独立Web服务(REST,XML,API-KEY)

  1. 身份验证:用户登录,注销
  2. 数据:获取产品列表
  3. 然后我将用不同的语言(Flash,PHP,JavaScript)创建客户端。数据仅提供给经过身份验证的用户。

    用户获取产品列表的典型通信将是:

    1. (1个请求)登录/开始会话
    2. (1 request)获取产品列表
    3. (1 request)获取产品列表
    4. ...
    5. 好的......现在我遇到的问题是用户会话。假设我们想要构建Javascript客户端,我们实际上必须创建将与REST通信的PHP客户端(PHP了解REST API-KEY)并将信息转发给Javascript(CLIENT)吗?用户将通过PHP登录到REST服务器,然后通过PHP向REST服务器请求数据?

      问题:

      • 现在,PHP如何在REST服务器上存储有关打开的用户会话的信息?
      • 如果我的想法不好,那么正确的实施方式是什么?
      • 替代?

5 个答案:

答案 0 :(得分:7)

RESTful接口不存储有关特定用户会话的任何信息。客户的工作是保持其正在做的事情的信息。

通过在Authorization HTTP标头中提供信息,对每个请求进行身份验证。 IF 这会成为性能问题,然后查看优化性能的替代解决方案。

答案 1 :(得分:4)

对于您的第一个问题:对服务的XmlHttpRequest请求仍将传递cookie,cookie可用于传播会话ID。您甚至可以(假设最终用户的浏览器支持它)将cookie标记为“HttpOnly”以减少您的XSS占用空间。有关详细信息,请参阅Jeff Atwood's article

答案 2 :(得分:1)

您应该对用户身份验证使用HTTP身份验证,因此不需要进行任何类型的会话管理。

答案 3 :(得分:0)

如果你使用javascript足够智能的客户端类将API-KEY(登录时加载)附加到你的类将产生的每个XmlHttpRequest的头文件中,你就不需要PHP来存储API-KEY。

同样值得注意的是,API-KEY不一定意味着身份验证密钥。

答案 4 :(得分:0)

我面临同样的问题。我在php中使用了restserver。 当然,流量通过SSL连接。

当我想获得有关某个用户的信息时,我必须首先向其他服务器进行身份验证,然后才能获得他的信息。我想知道更好的方法吗?

类似文章:RESTful Authentication 好的资源也是OAuth2。 Google也使用oauth:

  

OAuth 2.0是适用于所有Google API的全新简化授权协议。 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');

Rest服务器

/**
 * 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);
   }