Функция для установки auth_token - PullRequest
0 голосов
/ 15 февраля 2011

В моей форме есть скрытое поле:

<input type="hidden" name="auth_token" value="<?php echo $auth_token; ?>">

Это значение также сохраняется в сеансе и переменной:

$_SESSION['auth_token'] = hash('sha256', rand() . time() . $_SERVER['HTTP_USER_AGENT']);  #  TODO: put this in a function
$auth_token = $_SESSION['auth_token'];

Когда форма отправлена, сравниваются два значения. Это базовый токен формы.

Должно ли это быть преобразовано в две функции или только одну при рефакторинге? set_form_token() и get_form_token(), get_form_token () возвращает значение сеанса, затем я могу сравнить его в своем основном коде. Как правильно это сделать?

EDIT:

Учитывая ответы Джоэла Л и Роберта Питта, я сделал следующее:

function set_auth_token()
{
   if (!isset($_SESSION['auth_token']))
   {
      $_SESSION['auth_token'] = hash('sha256', rand() . time() . $_SERVER['HTTP_USER_AGENT']);
   }
}

function get_auth_token()
{
   if (isset($_SESSION['auth_token']))
   {
      return $_SESSION['auth_token'];   
   }
   else
   {
      die('No auth token.');
   }
}

function check_auth_token()
{
   if (array_key_exists('auth_token', $_SESSION) && array_key_exists('auth_token', $_POST))
   {
      if ($_SESSION['auth_token'] === $_POST['auth_token'])
      {
         # what happens if user fills the form in wrong first time(?)
         $_SESSION['auth_token'] = hash('sha256', rand() . time() . $_SERVER['HTTP_USER_AGENT']);
      }
      else
      {
         return false;
      }
   }
   else
   {
      return false;
   }
}

Затем я могу проверить, возвращает ли check_auth_token значение false или нет, и затем записать его после отправки формы. Это будет приемлемо?

Ответы [ 2 ]

1 голос
/ 15 февраля 2011

В моем приложении на самом деле есть следующие вспомогательные функции для использования токенов:

generateToken() // generate and return hash, used in login process.
                // hash then saved to session

getToken() // returns user's token from session

tokenField() // shortcut for echo '<input type="hidden" ... value="getToken()" />';
             // used in page templates

checkToken() // get token from either 1) $_POST 2) request header or 3) $_GET
             // and compare with getToken(). generate error if invalid.

Функция checkToken () проверяет 3 местоположения, потому что запрос может быть GET или POST, и любой из них может бытьчерез AJAX.И у меня есть помощник AJAX, который автоматически вставляет токен в заголовок для каждого запроса).

Таким образом, мне нужно только checkToken() вызывать везде, где требуется проверка, и поэтому могу довольно легко изменить детали импелляции.

Например, я могу начать использовать одноразовые токены, изменив только getToken() и checkToken().

Если вы вручную сравниваете if (get_form_token() == $token) везде в вашем коде, у вас неттакая гибкость.

0 голосов
/ 15 февраля 2011

во-первых, вы должны точно понимать, что такое рабочий процесс, и Джоэл Л. объясняет это очень просто.

Вы должны инкапсулировать методы в классе, чтобы все было вместе, что-то вроде sp:

class FormTokenizer
{
    private $context = "";

    public function __construct($auth_token = "auth_token")
    {
        $this->context = $context;
    }

    public function generateToken()
    {
        $_SESSION[form_tokens][$this->context] = hash('sha256', rand() . time() . $_SERVER['HTTP_USER_AGENT']);
        return $this;
    }

    public function getToken()
    {
        return isset($_SESSION[form_tokens][$this->context]) ? $_SESSION[form_tokens][$this->context]  : false;
    }

    function generateField()
    {
        return sprintf('<input type="hidden" name="a_%s" value="%s">',$this->context,$this->getToken());
    }

    public function validateToken()
    {
        if(isset($_POST["a_" . $this->context]))
        {
            return $this->getToken() == $_POST["a_" . $this->context];
        }
        return false;
    }
}

и простое использование будет:

$Token = new FormTokenizer("registration");

if(isset($_POST))
{
    if($Token->validateToken() === false)
    {
        //Token Onvalid
    }
}

//Generate a fresh token.
$hidden_input = $Token->generateToken()->generateField();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...