Аутентификация на основе токена в php

У меня есть служба REST на моем веб-сервере, написанная на php. Мне было интересно, какая была бы лучшая аутентификация (помимо базовой аутентификации HTTP-доступа). Я слышал об аутентификации на токенах и хотел бы спросить, могут ли кто-нибудь объяснить основные шаги.

  • В GET: отображается ли токен? (разве это небезопасно?)
  • Как сделать токен действительным только в течение определенного времени?
  • ...

Клиент: Android/браузер; Сервер: Apache, PHP5

Ответ 1

Это можно сделать в любом случае, а значения в запросе GET на самом деле не более заметны, чем значения в запросе POST. Если кто-то может "увидеть" (т.е. Перехватить) запрос, он может видеть все, что вы отправляете. В конце концов, HTTP-запрос - это всего лишь куча HTTP-заголовков, за которыми следует тело. URL-адрес отправляется в первой строке GET /foo/bar HTTP/1.1, другие значения просто отправляются в разные строки, следующие строки.

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

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

Чтобы действительно использовать HTTP-протокол, как предполагалось, вы должны использовать заголовок Authorization HTTP:

Authorization: MyScheme 123456:abcde...

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

Я бы рекомендовал систему токенов или систему подписи запроса, причем последнее было очень предпочтительным. В системе подписи запроса клиент должен получить от вас токен. Затем он отправляет хэш этого токена и некоторые характеристики запроса для аутентификации запроса, например. sha1(Token + Timestamp + Request URL + Request Body). Ваш сервер может проверить это, если клиент не должен отправлять токен в виде обычного текста при каждом запросе.

Как сделать токен действительным только в течение определенного времени?

Вы сохраняете маркерную сторону с отметкой истечения срока действия и проверяете ее.

Ответ 2

Здесь question об аутентификации на основе токенов. Я думаю, что самая распространенная аутентификация на токенах сегодня - OAuth. Но чтобы ответить на ваши вопросы:

В GET: отображается ли токен? (разве это небезопасно?)

Вы можете передавать свои токены через HTTP-заголовки, чтобы их было не так легко увидеть. OAuth позволяет это. Обратите внимание, что маркеры все еще видны, они просто не находятся в параметрах запроса GET.

Как сделать токен действительным только в течение определенного времени?

Поскольку вы управляете (создаете) токены, вы можете установить даты истечения срока действия для каждого токена. При каждом запросе вашего API вы должны просто проверить хранилище маркеров (например, базу данных), если данный токен все еще действителен. Если это не так, вы можете прервать запрос (возможно, вернуть ошибку HTTP 401).

Ответ 3

Вы можете использовать fire-base php JWT (JSON Web Token) для аутентификации на токенах.

1) Установите php jwt, запустив команду композитора , необходимо, чтобы firebase/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')

После этого Создайте свой токен

$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];

предоставить этот токен вашему пользователю " $jwt". По каждому запросу пользователю необходимо отправить значение токена с каждым запросом для проверки пользователя.

 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();
           }

Вы можете получить пошаговые полные конфигурации для аутентификации на основе токена php