FIX: очередной срез по авторизации
This commit is contained in:
parent
6d0466ea12
commit
7887f95ac8
4 changed files with 163 additions and 19 deletions
|
@ -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'],
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue