Вход в учетную запись базы данных MySQL через PHP при реализации безопасности на уровне строк
Я нахожусь в стадии проекта, над которым я работаю, где я слишком много задумываюсь из-за слишком большого количества информации и недостаточного опыта работы с MySQL, поэтому я в значительной степени ищу здесь экспертов, которые скажут: "Замолчи и сделай этот." Я даже открыт для предположений, что весь мой подход тупой и должен быть пересмотрен. Единственными вещами в этом проекте, которые не подлежат обсуждению, является использование php и MySQL.
Поэтому я пытаюсь реализовать безопасность на уровне строк в MySQL. Прочитайте несколько хороших статей, объясняющих, что MySQL не имеет ролей, поэтому вам нужно либо использовать представление для каждой таблицы, для которой вам нужен FGAC, либо там, где выполняется фильтрация условий для идентифицируемой пользователем информации, такой как их идентификатор пользователя. Из-за относительной сложности базы данных и проблем безопасности самой базы данных я выбрал маршрут просмотра. Вот пример представления, которое у меня есть:
create OR replace view v_system_requirement (
sys_id,
req_id,
sysreq_notes,
rate_id,
range_id,
art_id,
)
as
select
system_requirement.org_id,
organization.org_name,
organization.org_parent_branch,
system.sys_id,
system.sys_name
from organization JOIN system USING (org_id)
where
organization.org_id IN
(select o.org_id from organization o JOIN user u ON o.org_parent_branch=u.org_id OR o.org_id=u.org_id WHERE u.user_email=substring_index(user(), '@', 2)
);
select * from v_user_reference;
Поскольку у каждого пользователя будет собственная учетная запись в базе данных, причем подавляющее большинство из них будут иметь возможность только выбирать, обновлять, вставлять и т. Д. Соответствующие представления, это прекрасно дает мне организацию, в которой работает пользователь, непосредственные дочерние организации организации пользователя. и любые системы, которые принадлежат любой из вышеупомянутых организаций. Имена пользователей - это их адреса электронной почты, следовательно, 2 в substring_index пользовательской функции, и их пароли достаточно хешированы.
Суть здесь в том, что я добавляю веб-интерфейс. Очевидно, что когда пользователь входит в систему со своим именем пользователя и паролем, они будут переданы в базу данных через mysqli_connect(). Насколько мне известно, лучше всего закрывать соединение после каждой транзакции или группы транзакций.
Таким образом, возникает вопрос, как пользователь подключается под своей учетной записью базы данных? Я, очевидно, не собираюсь просить его повторно вводить свой пароль каждый раз. И сохранение хешированного пароля в переменной $_SESSION - плохая идея, верно? Учитывая это, есть ли что-то, что можно сделать на стороне MySQL, чтобы подключиться как более общая учетная запись, но настроить пользователя как самого себя так, чтобы user() возвращал его действительное имя учетной записи базы данных?
Или, как я спросил в начале, этот подход просто тупой и его следует отказаться в пользу лучшей практики? Спасибо за любую информацию, которую вы можете предоставить.
1 ответ
Обычно в приложениях PHP/MySQL существует одна учетная запись для доступа приложения к базе данных. Это будет храниться в каком-либо файле конфигурации или в вашем классе, который создает соединение с базой данных.
Затем вы будете хранить данные вашего пользователя в users
стол, и вы могли бы также иметь roles
/permissions
таблица, которая присоединяется к каждому пользователю через user_permissions
/user_roles
Таблица.
Таким образом, пользователь может войти в систему и пройти аутентификацию, сопоставив его учетные данные с его строкой в базе данных, и вы сможете управлять тем, какие у него есть разрешения, и вам не придется беспокоиться о том, что он все время вводит свой пароль для входа в систему. база данных, так как приложение входит в базу данных, а не пользователя.
Используя учебник W3Schools в качестве основы, он будет выглядеть примерно так:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// prepare and bind
$stmt = $conn->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $_POST['email']);
$stmt->execute();
$user = $stmt->fetch_assoc();
if(password_verify($_POST['password'], $user['password']))
{
echo "User authenticated";
}
else
{
echo "DENIED!!";
}
?>
Вы можете сохранить тот факт, что ваш пользователь аутентифицирован в $_SESSION
переменная, и пусть ваш код приложения проверит эту переменную, чтобы увидеть, следует ли разрешить пользователю оставаться на "панели управления" или быть перенаправлен обратно на страницу входа.