FIX: очередной срез по авторизации

This commit is contained in:
Evg 2021-03-24 13:09:38 +03:00
parent 6d0466ea12
commit 7887f95ac8
4 changed files with 163 additions and 19 deletions

View file

@ -141,7 +141,8 @@ class AuthController extends \MainController
// Страница авторизации
public function loginPage()
{
UserModel::checkCookie();
if(Request::getSession('account')) {
redirect('/');
}
@ -160,8 +161,9 @@ class AuthController extends \MainController
public function loginHandler()
{
$email = Request::getPost('email');
$password = Request::getPost('password');
$email = Request::getPost('email');
$password = Request::getPost('password');
$rememberMe = Request::getPost('rememberme');
if (!$this->checkEmail($email)) {
Base::addMsg('Недопустимый email', 'error');
@ -186,6 +188,12 @@ class AuthController extends \MainController
redirect('/login');
} else {
// Если нажал "Запомнить"
// Устанавливает сеанс пользователя и регистрирует его
if ($rememberMe == '1') {
UserModel::rememberMe($uInfo['id']);
}
$user = [
'user_id' => $uInfo['id'],
'login' => $uInfo['login'],

View file

@ -24,11 +24,15 @@ class PostController extends \MainController
include HLEB_GLOBAL_DIRECTORY . '/app/Optional/404.php';
hl_preliminary_exit();
}
// Array ( [id] => 6 [login] => AdreS [name] => Олег [email] => ss@sdf.ru [trust_level] => 1 [about] => Тестовый аккаунт [avatar] => [isLoggedIn] => 1 [ipaddress] => 127.0.0.1 )
//print_r(Request::getSession('account'));
//exit;
if($account = Request::getSession('account')){
// Получаем все теги отписанные участником
$space_user = SpaceModel::getSpaceUser($account['user_id']);
$user_id = $account['user_id'];
$space_user = SpaceModel::getSpaceUser($account['id']);
$user_id = $account['id'];
} else {
$space_user = [];
$user_id = 0;

View file

@ -8,8 +8,8 @@ class Base
public static function getUid() {
$user = Request::getSession('account') ?? [];
$uid = [];
if (!empty($user['user_id'])) {
$uid['id'] = $user['user_id'];
if (!empty($user['id'])) {
$uid['id'] = $user['id'];
$uid['login'] = $user['login'] ?? 'undefined';
$uid['trust_level'] = $user['trust_level'];
$uid['notif'] = NotificationsModel::usersNotification($uid['id']);
@ -362,4 +362,42 @@ class Base
return mb_strlen($str, "utf-8");
}
// Создать случайную строку (мы используем crypto)
public static function randomString(string $type = 'alnum', int $len = 8): string
{
switch ($type)
{
case 'alnum':
case 'numeric':
case 'nozero':
case 'alpha':
switch ($type)
{
case 'alpha':
$pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
break;
case 'alnum':
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
break;
case 'numeric':
$pool = '0123456789';
break;
case 'nozero':
$pool = '123456789';
break;
}
// @phpstan-ignore-next-line
return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
case 'md5':
return md5(uniqid((string) mt_rand(), true));
case 'sha1':
return sha1(uniqid((string) mt_rand(), true));
case 'crypto':
return bin2hex(random_bytes($len / 2));
}
// 'basic' type treated as default
return (string) mt_rand();
}
}

View file

@ -3,6 +3,7 @@
namespace App\Models;
use Hleb\Constructor\Handlers\Request;
use XdORM\XD;
use Base;
class UserModel extends \MainModel
{
@ -40,7 +41,7 @@ class UserModel extends \MainModel
public static function getUserId($id)
{
$query = XD::select(['id', 'login', 'name', 'email', 'avatar', 'about', 'created_at'])
$query = XD::select(['id', 'login', 'name', 'email', 'avatar', 'about', 'trust_level'])
->from(['users'])
->where(['id'], '=', $id);
@ -256,9 +257,102 @@ class UserModel extends \MainModel
}
////// ЗАПОМНИТЬ МЕНЯ
////// Работа с токенамм
////// Работа с токенами и куки
// Проверяет, устанавливался ли когда-либо файл cookie «запомнить меня»
// Если мы найдем, проверьте его по нашей таблице users_auth_tokens и
// если мы найдем совпадение, и оно все ещё в силе.
public static function checkCookie()
{
// Есть "remember" куки?
$remember = Request::getCookie('remember');
//print_r($remember);
//exit;
// Нет
if (empty($remember)) {
return;
}
// Получим наш селектор | значение валидатора
[$selector, $validator] = explode(':', $remember);
$validator = hash('sha256', $validator);
$token = self::getAuthTokenBySelector($selector);
public function rememberMe($uid)
if (empty($token)) {
return false;
}
// Хэш не соответствует
if (!hash_equals($token['auth_hashedvalidator'], $validator)) {
return false;
}
// Получение данных по id
$user = self::getUserId($token['auth_user_id']);
//print_r($user);
//exit;
// Нет пользователя
if (empty($user)) {
return false;
}
// ПРОСТО ПЕРЕД УСТАНОВКОЙ ДАННЫХ СЕССИИ И ВХОДОМ ПОЛЬЗОВАТЕЛЯ
// ДАВАЙТЕ ПРОВЕРИМ, НУЖЕН ЛИ ИХ ПРИНУДИТЕЛЬНЫЙ ВХОД
// Перенесем в конфиг?
$forceLogin = 0;
if ($forceLogin > 1) {
// ПОЛУЧАЕТ СЛУЧАЙНОЕ ЧИСЛО ОТ 1 до 100
// ЕСЛИ ЭТО НОМЕР МЕНЬШЕ ЧЕМ НОМЕР В НАСТРОЙКАХ ПРИНУДИТЕЛЬНОГО ВХОДА
// УДАЛИТЬ ТОКЕН ИЗ БД
if (rand(1, 100) < $forceLogin) {
self::DeleteTokenByUserId($token['auth_user_id']);
return;
}
}
// Сессия участника
self::setUserSession($user, '1');
$uid = $token['auth_user_id'];
self::rememberMeReset($uid, $selector);
return;
}
public static function setUserSession($user)
{
$data = [
'id' => $user['id'],
'login' => $user['login'],
'name' => $user['name'],
'email' => $user['email'],
'trust_level' => $user['trust_level'],
'about' => $user['about'],
'avatar' => $user['avatar'],
'isLoggedIn' => true,
'ipaddress' => Request::getRemoteAddress(),
];
$_SESSION['account'] = $data;
//redirect('/');
return true;
}
public static function rememberMe($uid)
{
// НАСТРОЕМ НАШ СЕЛЕКТОР, ВАЛИДАТОР И СРОК ДЕЙСТВИЯ
@ -268,8 +362,8 @@ class UserModel extends \MainModel
// если селектор (id) найден в таблице auth_tokens, мы затем сопоставляем валидаторы
$rememberMeExpire = 30;
$selector = random_string('crypto', 12);
$validator = random_string('crypto', 20);
$selector = Base::randomString('crypto', 12);
$validator = Base::randomString('crypto', 20);
$expires = time() + 60 * 60 * 24 * $rememberMeExpire;
// Установим токен
@ -322,11 +416,11 @@ class UserModel extends \MainModel
if (empty($existingToken)) {
return $this->rememberMe($uid);
return self::rememberMe($uid);
}
$rememberMeExpire = 30;
$validator = random_string('crypto', 20);
$validator = Base::randomString('crypto', 20);
$expires = time() + 60 * 60 * 24 * $rememberMeExpire;
// Установить
@ -342,7 +436,7 @@ class UserModel extends \MainModel
// Массивы данных установим
$data = [
'hashedvalidator' => hash('sha256', $validator),
'expires' => date('Y-m-d H:i:s', $expires),
'expires' => date('Y-m-d H:i:s', $expires)
];
} else {
$data = [
@ -391,7 +485,7 @@ class UserModel extends \MainModel
return true;
}
public function DeleteTokenByUserId($uid)
public static function DeleteTokenByUserId($uid)
{
XD::deleteFrom(['users_auth_tokens'])->where(['auth_user_id'], '=', $uid)->run();
@ -399,10 +493,10 @@ class UserModel extends \MainModel
return true;
}
public function UpdateSelector($data, $selector)
public static function UpdateSelector($data, $selector)
{
XD::update(['users_auth_tokens'])->set(['auth_user_id'], '=', $data['user_id'], ',', ['auth_selector'], '=', $data['selector'], ',', ['auth_hashedvalidator'], '=', $data['hashedvalidator'], ',', ['auth_expires'], '=', $data['expires'])->where(['auth_selector'], '=', $data['selector'])->run();
XD::update(['users_auth_tokens'])->set(['auth_hashedvalidator'], '=', $data['hashedvalidator'], ',', ['auth_expires'], '=', $data['expires'])->where(['auth_selector'], '=', $selector)->run();
return true;
@ -414,7 +508,7 @@ class UserModel extends \MainModel
{
return XD::select('*')->from(['users_auth_tokens'])
->where(['selector'], '=', $selector)->getSelectOne();
->where(['auth_selector'], '=', $selector)->getSelectOne();
}