Многие базовые схемы виртуальных URL-адресов могут быть достигнуты без использования RewriteRules. Apache позволяет запускать скрипты PHP без расширения .php
и с виртуальным аргументом PATH_INFO
.
AcceptPathInfo On
часто включается по умолчанию. В основном это позволяет .php
и другим URL-адресам ресурсов переносить виртуальный аргумент: http://example.com/script.php/virtual/path
Теперь этот /virtual/path
отображается в PHP как $_SERVER["PATH_INFO"]
, где вы можете обрабатывать любые дополнительные аргументы, как вам нравится. Это не так удобно, как разделить сегменты входного пути Apache на $1
, $2
, $3
и передать их как различные переменные $_GET
в PHP. .php
.php
«Расширения файлов» в URL-адресах разрешены: Options +MultiViews
Это означает, что Apache выбирает article.php
для HTTP-запросов на /article
из-за соответствующего базового имени. И это хорошо работает вместе с вышеупомянутой функцией PATH_INFO. Таким образом, вы можете просто использовать URL-адреса, такие как http://example.com/article/virtual/title
. Это имеет смысл, если у вас есть традиционное веб-приложение с несколькими точками / сценариями PHP-скриптов. Обратите внимание, что MultiViews имеет другую / более широкую цель. Это повлечет за собой незначительное исполнение, потому что Apache всегда ищет другие файлы с соответствующими базовыми именами. Это фактически означает Content-Negotiation , поэтому браузеры получают лучшую альтернативу доступным ресурсам (например, article.en.php
, article.fr.php
, article.jp.mp4
). .php
.php
в URL-адресах, - это настройка обработчика PHP для других файловых схем. Самый простой вариант - переопределить тип MIME / обработчика по умолчанию через .htaccess
: DefaultType application/x-httpd-php
Таким образом, вы можете просто переименовать свой скрипт article.php
только в article
(без расширения), но все же обработать его как PHP-скрипт. Теперь это может иметь некоторые последствия для безопасности и производительности, поскольку теперь все файлы без расширения будут переданы через PHP. Поэтому вы можете альтернативно установить это поведение только для отдельных файлов:
SetHandler application/x-httpd-php
# or SetType
Это несколько зависит от настройки вашего сервера и используемого PHP SAPI. Общие альтернативы включают ForceType application/x-httpd-php
или AddHandler php5-script
. Снова обратите внимание, что такие настройки распространяются от одного .htaccess
до подпапок. Вы всегда должны отключать выполнение сценария (SetHandler None
и Options -Exec
или php_flag engine off
и т. Д.) Для статических ресурсов и загрузки / каталогов и т. Д. mod_alias
, которые иногда работают так же хорошо, как и mod_rewrite
s RewriteRules. Обратите внимание, что большинство из них должны быть настроены в разделе
, но не в файлах конфигурации .htaccess
для каждого каталога. ScriptAliasMatch
в первую очередь предназначен для скриптов CGI, но также должен работать для PHP. Он позволяет регулярные выражения так же, как и любые RewriteRule
. На самом деле это, пожалуй, самый надежный вариант для конфигурирования переднего контроллера. И простой Alias
помогает с несколькими простыми схемами перезаписи. Даже простая директива ErrorDocument
может использоваться, чтобы позволить скрипту PHP обрабатывать виртуальные пути. Обратите внимание, что это обходное решение kludgy, однако, запрещает все, кроме запросов GET, и наводняет error.log по определению. См. http://httpd.apache.org/docs/2.2/urlmapping.html для получения дополнительных советов. Использование password_hash
- рекомендуемый способ хранения паролей. Не разделяйте их на БД и файлы.
Допустим, у нас есть следующий ввод:
$password = $_POST['password'];
Я не проверяю ввод только ради понимания концепции .
Сначала вы вводите пароль:
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
Затем см. вывод:
var_dump($hashed_password);
Как вы видите, это хешировано. (Я предполагаю, что вы сделали эти шаги).
Теперь вы храните этот hashed_password в своей базе данных, а затем скажем, когда пользователь просит их войти в систему. Вы проверяете ввод пароля с этим значением хэша в базе данных , сделав это:
// Query the database for username and password
// ...
if(password_verify($password, $hashed_password)) {
// If the password inputs matched the hashed password in the database
// Do something, you know... log them in.
}
// Else, Redirect them back to the login page.
Да, это правда. Почему вы сомневаетесь в php faq для функции? :)
Результат работы password_hash()
имеет четыре части:
Итак, как вы видите, хэш является его частью.
Конечно, у вас может быть дополнительная соль для дополнительного уровня безопасности, но я, честно говоря, считаю, что это избыток в регулярном php-приложении. Алгоритм bcrypt по умолчанию хорош, и, возможно, дополнительный вариант blowfish еще лучше.
Никогда не используйте md5 () для защиты вашего пароля, даже с солью, это всегда опасно!
Сделайте свой пароль с последними алгоритмами хеширования, как показано ниже.
<?php
// Your original Password
$password = '121@121';
//PASSWORD_BCRYPT or PASSWORD_DEFAULT use any in the 2nd parameter
/*
PASSWORD_BCRYPT always results 60 characters long string.
PASSWORD_DEFAULT capacity is beyond 60 characters
*/
$password_encrypted = password_hash($password, PASSWORD_BCRYPT);
?>
Для сопоставления с зашифрованным паролем базы данных и введенным пользователем паролем используйте следующую функцию.
<?php
if (password_verify($password_inputted_by_user, $password_encrypted)) {
// Success!
echo 'Password Matches';
}else {
// Invalid credentials
echo 'Password Mismatch';
}
?>
Если вы хотите использовать свою соль, используйте свою настраиваемую функцию для нее, просто следуйте ниже, но я не рекомендую это, поскольку он найден устаревшим в последних версиях PHP.
прочитайте это http://php.net/manual/en/function.password-hash.php до используйте ниже код.
<?php
$options = [
'salt' => your_custom_function_for_salt(),
//write your own code to generate a suitable & secured salt
'cost' => 12 // the default cost is 10
];
$hash = password_hash($your_password, PASSWORD_DEFAULT, $options);
?>
Надеюсь, что все это поможет !!
Да, вы поняли это правильно, функция password_hash () будет генерировать соль сама по себе и включает ее в полученное хеш-значение.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $existingHashFromDb);
Вторая соль, которую вы упомянули (тот, который хранится в файле), на самом деле является перцем или серверной стороной ключ. Если вы добавите его перед хэшированием (например, соль), добавьте перец. Однако есть лучший способ, вы можете сначала вычислить хэш, а затем зашифровать (двухсторонний) хеш с помощью серверного ключа. Это дает вам возможность поменять ключ при необходимости.
В отличие от соли, этот ключ следует хранить в секрете. Люди часто смешивают его и пытаются скрыть соль, но лучше разрешить соль выполнять свою работу и добавить секрет с помощью ключа.
Существует явное отсутствие обсуждения обратной и передовой совместимости, встроенной в функции паролей PHP. Примечательно:
crypt()
и по своей сути обратно совместимы с crypt()
-форматными хэшами , даже если они используют устаревшие и / или небезопасные алгоритмы хеширования. password_needs_rehash()
и немного логики в ваш рабочий процесс проверки подлинности могут сохранить ваши хэши до дата с текущими и будущими алгоритмами с потенциально нулевыми будущими изменениями рабочего процесса. Примечание. Любая строка, которая не соответствует указанному алгоритму, будет помечена для необходимости переименования, включая хэши, не связанные с склепом. Например:
class FakeDB {
public function __call($name, $args) {
printf("%s::%s(%s)\n", __CLASS__, $name, json_encode($args));
return $this;
}
}
class MyAuth {
protected $dbh;
protected $fakeUsers = [
// old crypt-md5 format
1 => ['password' => '$1$AVbfJOzY$oIHHCHlD76Aw1xmjfTpm5.'],
// old salted md5 format
2 => ['password' => '3858f62230ac3c915f300c664312c63f', 'salt' => 'bar'],
// current bcrypt format
3 => ['password' => '$2y$10$3eUn9Rnf04DR.aj8R3WbHuBO9EdoceH9uKf6vMiD7tz766rMNOyTO']
];
public function __construct($dbh) {
$this->dbh = $dbh;
}
protected function getuser($id) {
// just pretend these are coming from the DB
return $this->fakeUsers[$id];
}
public function authUser($id, $password) {
$userInfo = $this->getUser($id);
// Do you have old, turbo-legacy, non-crypt hashes?
if( strpos( $userInfo['password'], '$' ) !== 0 ) {
printf("%s::legacy_hash\n", __METHOD__);
$res = $userInfo['password'] === md5($password . $userInfo['salt']);
} else {
printf("%s::password_verify\n", __METHOD__);
$res = password_verify($password, $userInfo['password']);
}
// once we've passed validation we can check if the hash needs updating.
if( $res && password_needs_rehash($userInfo['password'], PASSWORD_DEFAULT) ) {
printf("%s::rehash\n", __METHOD__);
$stmt = $this->dbh->prepare('UPDATE users SET pass = ? WHERE user_id = ?');
$stmt->execute([password_hash($password, PASSWORD_DEFAULT), $id]);
}
return $res;
}
}
$auth = new MyAuth(new FakeDB());
for( $i=1; $i<=3; $i++) {
var_dump($auth->authuser($i, 'foo'));
echo PHP_EOL;
}
Выход:
MyAuth::authUser::password_verify
MyAuth::authUser::rehash
FakeDB::prepare(["UPDATE users SET pass = ? WHERE user_id = ?"])
FakeDB::execute([["$2y$10$zNjPwqQX\/RxjHiwkeUEzwOpkucNw49yN4jjiRY70viZpAx5x69kv.",1]])
bool(true)
MyAuth::authUser::legacy_hash
MyAuth::authUser::rehash
FakeDB::prepare(["UPDATE users SET pass = ? WHERE user_id = ?"])
FakeDB::execute([["$2y$10$VRTu4pgIkGUvilTDRTXYeOQSEYqe2GjsPoWvDUeYdV2x\/\/StjZYHu",2]])
bool(true)
MyAuth::authUser::password_verify
bool(true)
В качестве последней заметки, учитывая, что вы можете только повторно использовать пароль пользователя при входе в систему, вам следует подумать о том, чтобы «задерживать» ненадежные устаревшие хэши для защиты ваших пользователей. Под этим я подразумеваю, что после определенного льготного периода вы удаляете все неуверенные [например: голые MD5 / SHA / иначе слабые] хэши и заставляете своих пользователей полагаться на механизмы сброса пароля вашего приложения.
Я создал функцию, которую я все время использую для проверки пароля и создания паролей, например. для их хранения в базе данных MySQL. Он использует случайно сгенерированную соль, которая более безопасна, чем использование статической соли.
function secure_password($user_pwd, $multi) {
/*
secure_password ( string $user_pwd, boolean/string $multi )
*** Description:
This function verifies a password against a (database-) stored password's hash or
returns $hash for a given password if $multi is set to either true or false
*** Examples:
// To check a password against its hash
if(secure_password($user_password, $row['user_password'])) {
login_function();
}
// To create a password-hash
$my_password = 'uber_sEcUrE_pass';
$hash = secure_password($my_password, true);
echo $hash;
*/
// Set options for encryption and build unique random hash
$crypt_options = ['cost' => 11, 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)];
$hash = password_hash($user_pwd, PASSWORD_BCRYPT, $crypt_options);
// If $multi is not boolean check password and return validation state true/false
if($multi!==true && $multi!==false) {
if (password_verify($user_pwd, $table_pwd = $multi)) {
return true; // valid password
} else {
return false; // invalid password
}
// If $multi is boolean return $hash
} else return $hash;
}
salt
, он будет автоматически сгенерирован функцией password_hash () , следуя рекомендациям. Вместо PASSWORD_BCRYPT
можно использовать PASSWORD_DEFAULT
для записи будущего кода.
– martinstoeckli
23 August 2017 в 11:29