2012-03-01 43 views
10

Tôi có dịch vụ REST trên máy chủ web của mình, được viết bằng php. Tôi đã tự hỏi, những gì sẽ là xác thực tốt nhất (bên cạnh xác thực truy cập http cơ bản). Tôi đã nghe về auth dựa trên mã thông báo và muốn hỏi xem ai đó có thể giải thích các bước chính hay không.xác thực dựa trên mã thông báo trong php

  • Trên GET: Mã thông báo có được hiển thị không? (không phải là không an toàn?)
  • Làm cách nào để mã thông báo chỉ hợp lệ trong một thời gian cụ thể?
  • ...

Khách hàng: Android/Trình duyệt; Máy chủ: Apache, PHP5

+0

làm cho nó lĩnh vực như ẩn thông qua phương thức POST –

+6

những gì sẽ là cảm giác của một dịch vụ RESTfull nếu tôi chỉ có thể sử dụng POST;) tôi đã thực hiện PUT, POST, GET, DELETE, trong Tất nhiên, có một chức năng khác nhau cho mỗi phương pháp http –

+0

để ẩn hiển thị mã thông báo của bạn –

Trả lời

12

Có thể thực hiện theo cách này và giá trị trong yêu cầu GET không thực sự rõ ràng hơn giá trị trong yêu cầu POST. Nếu bất kỳ ai có thể "xem" (tức là chặn) yêu cầu, anh ấy có thể xem mọi thứ bạn đang gửi. Cuối cùng, một yêu cầu HTTP chỉ là một loạt các tiêu đề HTTP có thể được theo sau bởi một phần thân. URL được gửi trong dòng GET /foo/bar HTTP/1.1 đầu tiên, các giá trị khác chỉ gửi trong các dòng khác nhau, sau đây.

Vì vậy, tùy thuộc vào bạn nơi bạn mong đợi mã thông báo xác thực được gửi. Bạn có thể yêu cầu nó là một tham số truy vấn được nối vào mọi yêu cầu:

GET /foo/bar?user=123456&token=abcde... 

Để thực sự sử dụng giao thức HTTP như dự định tuy nhiên, bạn nên sử dụng tiêu đề Authorization HTTP:

Authorization: MyScheme 123456:abcde... 

Nội dung của tiêu đề này hoàn toàn tùy thuộc vào bạn. Nó thường chỉ định một phương thức ủy quyền như Basic, theo sau là bất kỳ điều gì bạn muốn yêu cầu xác thực. Điều này có thể chỉ đơn giản là tên người dùng và mật khẩu, một băm của họ, một mã thông báo mờ mà khách hàng đã thu được tại một số điểm hoặc bất kỳ điều gì khác thực sự.

Tôi muốn giới thiệu hệ thống mã thông báo hoặc hệ thống ký yêu cầu, và hệ thống này được ưu tiên hơn rất nhiều. Trong hệ thống ký yêu cầu, khách hàng phải lấy mã thông báo từ bạn. Sau đó, nó sẽ gửi một mã băm của mã thông báo này và các đặc điểm nhất định của yêu cầu để xác thực yêu cầu, ví dụ: sha1(Token + Timestamp + Request URL + Request Body). Máy chủ của bạn có thể xác thực điều này mà không cần khách hàng phải gửi mã thông báo bằng văn bản thuần túy trên mỗi yêu cầu.

Làm cách nào để mã thông báo chỉ hợp lệ trong một thời gian cụ thể?

Bạn lưu phía máy chủ mã thông báo bằng dấu thời gian hết hạn và kiểm tra lại.

+0

Cảm ơn, tôi nghĩ rằng tôi đã có ý tưởng cơ bản ngay bây giờ. Chỉ còn một vài câu hỏi về điều đó: 1. Khi khách hàng nhận được mã thông báo - đây sẽ là một 'tệp json đơn giản', ví dụ, chứa "TOKEN_A"? 2. Nếu khách hàng chỉ gửi một băm, bao gồm dấu thời gian, làm cách nào để kiểm tra phía máy chủ nếu băm hợp lệ? lặp lại các băm có thể có của las X ms? –

+3

1. Có, bất cứ điều gì phù hợp với mô hình của bạn tốt nhất. Có thể người dùng cần đăng ký trên trang web và sao chép và dán mã thông báo từ đó. Có thể bạn cũng làm điều đó thông qua một API, trong trường hợp này, một phản hồi JSON là tốt. 2. Tiêu đề 'Authorization' cần chứa id người dùng và hash mã thông báo. Yêu cầu này cũng phải chứa dấu thời gian, ví dụ trong tiêu đề 'Date', tiêu chuẩn này khá chuẩn. Hàm băm sẽ dựa trên tiêu đề 'Ngày' theo nghĩa đen. Máy chủ của bạn chỉ tra cứu mã thông báo cho người dùng, đảm bảo Ngày nằm trong khoảng ± vài phút của thời gian hiện tại và tạo lại cùng một mã băm. – deceze

+1

Vì vậy, ý tưởng cơ bản là: thay vì gửi đồng bằng mã thông báo, tôi gửi cho bạn băm và thông tin A, B, C. Server nhận được token từ UID, băm nó với thông tin A, B, C. và kiểm tra xem các băm có giống nhau không ?! - (+ nhân viên xác nhận thời gian) - đó là khá thông minh: D Cảm ơn rất nhiều –

2

Đây là số question về xác thực dựa trên mã thông báo. Tôi cho rằng xác thực dựa trên mã thông báo phổ biến nhất hiện nay là OAuth. Nhưng để trả lời câu hỏi của bạn:

Khi nhận được: Mã thông báo có được hiển thị không? (không phải là không an toàn?)

Bạn có thể chuyển mã thông báo của bạn thông qua tiêu đề HTTP để chúng không dễ thấy. OAuth allows this. Lưu ý rằng các mã thông báo vẫn hiển thị, chúng chỉ không có trong tham số truy vấn GET.

Làm cách nào để mã thông báo chỉ hợp lệ trong một thời gian cụ thể?

Vì bạn kiểm soát (tạo) mã thông báo, bạn có thể đặt ngày hết hạn cho mỗi mã thông báo. Trên mọi yêu cầu của API, bạn chỉ nên kiểm tra bộ nhớ mã thông báo của mình (ví dụ: Cơ sở dữ liệu) nếu mã thông báo đã cho vẫn hợp lệ. Nếu không, bạn có thể hủy yêu cầu (có thể trả lại lỗi HTTP 401).

+0

cảm ơn, tôi sẽ xem xét OAuth. Tôi nghĩ rằng tôi đã có ý tưởng cơ bản ngay bây giờ :) –

+0

Cả POST và GET tương đối không an toàn. Để làm cho chúng an toàn, bạn cần một lớp mã hóa khác ở trên cùng, chẳng hạn như SSL. –

1

Bạn có thể sử dụng JWT cơ sở lửa lửa (Mã thông báo Web JSON) để xác thực dựa trên mã thông báo.

1) Cài đặt php JWT bằng cách chạy lệnh soạn nhà soạn nhạc yêu cầu căn cứ hỏa lực/php-JWT

require_once('vendor/autoload.php'); 
    use \Firebase\JWT\JWT; 
    define('SECRET_KEY','Your-Secret-Key') // secret key can be a random string and keep in secret from anyone 
    define('ALGORITHM','HS512') 

Sau đó Tạo của bạn thẻ

$tokenId = base64_encode(mcrypt_create_iv(32)); 
       $issuedAt = time(); 
       $notBefore = $issuedAt + 10; //Adding 10 seconds 
       $expire  = $notBefore + 7200; // Adding 60 seconds 
       $serverName = 'http://localhost/php-json/'; /// set your domain name 


       /* 
       * Create the token as an array 
       */ 
       $data = [ 
        'iat' => $issuedAt,   // Issued at: time when the token was generated 
        'jti' => $tokenId,   // Json Token Id: an unique identifier for the token 
        'iss' => $serverName,  // Issuer 
        'nbf' => $notBefore,  // Not before 
        'exp' => $expire,   // Expire 
        'data' => [     // Data related to the logged user you can set your required data 
       'id' => "set your current logged user-id", // id from the users table 
       'name' => "logged user name", // name 
           ] 
       ]; 
       $secretKey = base64_decode(SECRET_KEY); 
       /// Here we will transform this array into JWT: 
       $jwt = JWT::encode(
         $data, //Data to be encoded in the JWT 
         $secretKey, // The signing key 
         ALGORITHM 
         ); 
      $unencodedArray = ['jwt' => $jwt]; 

cung cấp thẻ này để người dùng của bạn "$ jwt ". Trên mỗi người dùng yêu cầu cần gửi giá trị mã thông báo với mỗi yêu cầu để xác thực người dùng.

try { 
      $secretKey = base64_decode(SECRET_KEY); 
      $DecodedDataArray = JWT::decode($_REQUEST['tokVal'], $secretKey, array(ALGORITHM)); 

      echo "{'status' : 'success' ,'data':".json_encode($DecodedDataArray)." }";die(); 

      } catch (Exception $e) { 
      echo "{'status' : 'fail' ,'msg':'Unauthorized'}";die(); 
      } 

You can get step by step full configurations for php token based authentication

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