ECMAScript 6 имеет «генераторы», которые позволяют вам легко программировать в асинхронном стиле.
function* myGenerator() {
const callback = yield;
let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
console.log("response is:", response);
// examples of other things you can do
yield setTimeout(callback, 1000);
console.log("it delayed for 1000ms");
while (response.statusText === "error") {
[response] = yield* anotherGenerator();
}
}
Для запуска вышеуказанного кода вы делаете это:
const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function
Если вам нужно настроить таргетинг на браузеры, которые не поддерживают ES6, вы можете запустить код через Babel или short-compiler для генерации ECMAScript 5.
Обратный вызов ...args
завернут в массив и разрушен, когда вы их читаете так что шаблон может справиться с обратными вызовами, которые имеют несколько аргументов. Например, с узлом fs :
const [err, data] = yield fs.readFile(filePath, "utf-8", callback);
Использование 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;
}