Мистика - перестаёт пускать в админку и не только
Всем привет!
Кто-нибудь сталкивался с тем, что при правильном логине и пароле перестаёт пускать в админку? И так же не логинит на фронте с теми же пользовательскими данными сниппетом Login.
Запара какая-то непонятная.
С фронта анонимусы создают объявления, при помощи Тикетс. Модераторы и администраторы могут входить по логину и паролю.
Ситуация такая: я, как член группы «Administrators» залогинен в админке, затем захожу с помощью сниппета Login на фронт — всё нормально. Потом с фронта делаю логаут (для своих проверок), захожу снова — всё, "Неправильное имя пользователя или пароль. Проверьте введённые данные и попытайтесь снова.". Затем из админки делаю «Перезагрузить права доступа» и «Завершить все сеансы», меня разлогивает, захожу снова — та же песня — "Неправильное имя пользователя или пароль. Проверьте введённые данные и попытайтесь снова.".
При чём, после возникновения этой ошибки на фронте, простой логаут из админки — и всё, не пускает.
Данные верные (заполняются из менеджера паролей).
Папку с кэшем, куки, таблицу сессий — всё чистил. Система последняя — 2.2.8. Хостинг менял, история не изменилась.
И это происходит не только с главным админом, а со всеми пользователями.
Помогает только принудительное изменение пароля напрямую в базе.
И вот сижу я сейчас без доступа в админку, ибо пароль постоянно менять тупо задолбало :-(
В общем мистика.
Кто-нибудь сталкивался с тем, что при правильном логине и пароле перестаёт пускать в админку? И так же не логинит на фронте с теми же пользовательскими данными сниппетом Login.
Запара какая-то непонятная.
С фронта анонимусы создают объявления, при помощи Тикетс. Модераторы и администраторы могут входить по логину и паролю.
Ситуация такая: я, как член группы «Administrators» залогинен в админке, затем захожу с помощью сниппета Login на фронт — всё нормально. Потом с фронта делаю логаут (для своих проверок), захожу снова — всё, "Неправильное имя пользователя или пароль. Проверьте введённые данные и попытайтесь снова.". Затем из админки делаю «Перезагрузить права доступа» и «Завершить все сеансы», меня разлогивает, захожу снова — та же песня — "Неправильное имя пользователя или пароль. Проверьте введённые данные и попытайтесь снова.".
При чём, после возникновения этой ошибки на фронте, простой логаут из админки — и всё, не пускает.
Данные верные (заполняются из менеджера паролей).
Папку с кэшем, куки, таблицу сессий — всё чистил. Система последняя — 2.2.8. Хостинг менял, история не изменилась.
И это происходит не только с главным админом, а со всеми пользователями.
Помогает только принудительное изменение пароля напрямую в базе.
И вот сижу я сейчас без доступа в админку, ибо пароль постоянно менять тупо задолбало :-(
В общем мистика.
Комментарии: 15
Ни разу такого не встречал.
А если попробовать зайти прям из другого брайзура?
Ошибки в логах на сервере есть?
Php-apc или другой кэшер включен?
А если попробовать зайти прям из другого брайзура?
Ошибки в логах на сервере есть?
Php-apc или другой кэшер включен?
А если попробовать зайти прям из другого брайзура?Так же ошибка
Ошибки в логах на сервере есть?Пусто :-(
Php-apc или другой кэшер включен?Вроде нет. Во всяком случае с кэшем не игрался и все настройки кэша по умолчанию из коробки.
Сейчас вообще жесть какая-то — после последней попытки логина через Login тупо перестала отображаться форма входа. Вот вообще нету. Папку с кэшем чистил несколько раз (мало ли). Раньше такого не было.
Вот прям не знаю чем помочь, ни разу такого не видал.
Эх, буду тогда по кускам сайт воссоздавать, других вариантов уже нету.
Спасибо вам!
Спасибо вам!
Корень проблемы нашёл — как обычно, ссзб.
В форме добавления нового тикета, кроме, собственно, полей тикета, так же есть поля для редактирования данных пользователя. И если пользователь залогинен, то данные автоматом подставляются в эти поля. Если не залогинен, то их надо вписать и юзер автоматом создастся и залогинится. Так вот при добавлении тикета поля пользователя обрабатываются отдельно — если надо — юзер создаётся, если что-то изменилось — юзер обновляется.
Так вот обновление юзера происходило вот так:
И фишка вышла такая — благодаря $user->toArray() в процессор передаётся так же поле текущего пароля. А точнее не сам пароль, а его хэш (в базе же пароли хешированные лежат). А процессор, получив заполненное поле пароля, делал из него новый хэш и его записывал. Соответственно, пароль-то фактически каждый раз менялся. Вот такой вот я балда :-)
Изначально я считал, что в процессор достаточно передать id-шник юзера и поля, которые надо изменить. А оказалось, что нифига — этому процессору обязательно нужны ещё логин и мыло (которое надо тянуть из профайла). Поэтому решил перебдеть, собрав все данные в кучу. И зря, как выяснилось)
Переделал на это и всё заработало:
Василий, я не зря отвечаю в этой ветке именно тебе, потому что в процессе копания выяснилась интересная особенность тикетов, возможно даже баг.
Помнишь, ты мне как-то помогал разобраться с изменением алиасов при создании тикетов? К алиасу добаляется id тикета в плагине на «OnDocFormSave» вот так:
У меня в сниппете myTicketForm в самом конце, после всех шаманств и отработки всех процессоров, идёт редирект на этот тикет:
И вот в чём дело — редирект происходит на uri со старым алиасом, т.е. на тот, который был до моих изменений! Хотя все плагины отработали и всё должно было измениться. Но и это не самое интересное — у самого тикета алиас сохранился таким, каким я его и сделал, с id-шником! Т.е. makeUrl берёт uri документа из какого-нибудь alias_map, а там данные ещё старые. В итоге редирект происходит на не существующий адрес. Но и это ещё не всё — страница открывается! xD
Т.е., положим у тикета сформировался такой алиас — 'this-is-ticket-alias'. В плагине к нему подставляется id тикета: '123-this-is-ticket-alias'. И этот алиас фактически у ресурса и записан, но в кэше лежит 'this-is-ticket-alias', и при редиректе на этот адрес открывается только что созданный тикет (хотя адрес-то фактически не существующий)!
И вот только после того, как в админке что-нибудь изменю/сохраню или просто тыкну «обновить сайт» — кэш очищается и по адресу 'this-is-ticket-alias' как и положено вылезает 404, а сам документ становится доступен по '123-this-is-ticket-alias'.
Такие дела.
В процессе копания пришёл к вот этому.
Заменил код метода на:
Потом заменил на одну строчку:
Выходит проблема именно в кэшировании тикетов. Точнее в очистке кэша.
Как-то так.
В форме добавления нового тикета, кроме, собственно, полей тикета, так же есть поля для редактирования данных пользователя. И если пользователь залогинен, то данные автоматом подставляются в эти поля. Если не залогинен, то их надо вписать и юзер автоматом создастся и залогинится. Так вот при добавлении тикета поля пользователя обрабатываются отдельно — если надо — юзер создаётся, если что-то изменилось — юзер обновляется.
Так вот обновление юзера происходило вот так:
function userUpdate ($user, $data) {
$result = array();
$userProfile = $user->getOne('Profile');
$userProfile = $userProfile->toArray();
// $changedData = array_diff($data, array_intersect_key($userProfile, $data));
$changedData = array_intersect_key($data, $userProfile);
if (count($changedData)) {
/**
* Всё внимание на массивы, которые передаются в процессор:
*/
$response = $this->modx->runProcessor('web/user/update', array_merge(
$userProfile,
$user->toArray(),
$changedData
));
if ($response->isError()) {
$errors = $this->getResponseErrors($response);
$result = array_merge($result, $errors);
}
$this->modx->error->reset();
}
return $result;
}
И фишка вышла такая — благодаря $user->toArray() в процессор передаётся так же поле текущего пароля. А точнее не сам пароль, а его хэш (в базе же пароли хешированные лежат). А процессор, получив заполненное поле пароля, делал из него новый хэш и его записывал. Соответственно, пароль-то фактически каждый раз менялся. Вот такой вот я балда :-)
Изначально я считал, что в процессор достаточно передать id-шник юзера и поля, которые надо изменить. А оказалось, что нифига — этому процессору обязательно нужны ещё логин и мыло (которое надо тянуть из профайла). Поэтому решил перебдеть, собрав все данные в кучу. И зря, как выяснилось)
Переделал на это и всё заработало:
function userUpdate ($user, $data) {
$result = array();
$userProfile = $user->getOne('Profile');
$userProfile = $userProfile->toArray();
// $changedData = array_diff($data, array_intersect_key($userProfile, $data));
$changedData = array_intersect_key($data, $userProfile);
if (count($changedData)) {
$response = $this->modx->runProcessor('web/user/update', array_merge(array(
'id' => $user->id,
'username' => $user->username,
'email' => $userProfile['email']
), $changedData));
if ($response->isError()) {
$errors = $this->getResponseErrors($response);
$result = array_merge($result, $errors);
}
$this->modx->error->reset();
}
return $result;
}
Василий, я не зря отвечаю в этой ветке именно тебе, потому что в процессе копания выяснилась интересная особенность тикетов, возможно даже баг.
Помнишь, ты мне как-то помогал разобраться с изменением алиасов при создании тикетов? К алиасу добаляется id тикета в плагине на «OnDocFormSave» вот так:
$resource = &$modx->event->params['resource'];
$alias = $resource->get('alias');
$alias = (strpos($alias, $id.'-') !== 0) ? $id.'-'.$alias : $alias;
$resource->set('alias', $alias);
$resource->save();
У меня в сниппете myTicketForm в самом конце, после всех шаманств и отработки всех процессоров, идёт редирект на этот тикет:
$redirectTo = $modx->makeUrl($result['id'],'','','full');
$modx->sendRedirect($redirectTo);
И вот в чём дело — редирект происходит на uri со старым алиасом, т.е. на тот, который был до моих изменений! Хотя все плагины отработали и всё должно было измениться. Но и это не самое интересное — у самого тикета алиас сохранился таким, каким я его и сделал, с id-шником! Т.е. makeUrl берёт uri документа из какого-нибудь alias_map, а там данные ещё старые. В итоге редирект происходит на не существующий адрес. Но и это ещё не всё — страница открывается! xD
Т.е., положим у тикета сформировался такой алиас — 'this-is-ticket-alias'. В плагине к нему подставляется id тикета: '123-this-is-ticket-alias'. И этот алиас фактически у ресурса и записан, но в кэше лежит 'this-is-ticket-alias', и при редиректе на этот адрес открывается только что созданный тикет (хотя адрес-то фактически не существующий)!
И вот только после того, как в админке что-нибудь изменю/сохраню или просто тыкну «обновить сайт» — кэш очищается и по адресу 'this-is-ticket-alias' как и положено вылезает 404, а сам документ становится доступен по '123-this-is-ticket-alias'.
Такие дела.
В процессе копания пришёл к вот этому.
Заменил код метода на:
$this->xpdo->cacheManager->refresh(array(
'db' => array(),
'auto_publish' => array('contexts' => array($this->context_key)),
'context_settings' => array('contexts' => array($this->context_key)),
'resource' => array('contexts' => array($this->context_key)),
));
Не помогло.Потом заменил на одну строчку:
$this->xpdo->reloadContext($this->context_key);
И всё встало на свои места, всё заработало как надо. Только вот теперь чистится весь кэш сайта, а собственная система кэширования тикетов получается не при делах :-(Выходит проблема именно в кэшировании тикетов. Точнее в очистке кэша.
Как-то так.
Менять alias нужно на событии OnBeforeDocFormSave, тогда карта алиасов обновится, и все должно быть ок.
Вот этот момент в процессоре.
Вот этот момент в процессоре.
Да, так работает, но id ресурса в событии OnBeforeDocFormSave ещё не известно!
А в OnDocFormSave известен id, но не обновляется карта алиасов. Как ж мне быть?
А в OnDocFormSave известен id, но не обновляется карта алиасов. Как ж мне быть?
Обновляй карту сам, в плагине OnDocFormSave.
Спасибо большое! Помогло :-)
Может попробовать обновить php с 5.2 на 5.3? Сейчас 5.2 стоит.
Не помогло обновление
Проблема возникла сама по себе? Никаких мыслей по этому поводу?
Да вот в том-то и дело, что предпосылок к такой проблеме нету совершенно. Обычный Login, обычное добавление ресурсов с фронтэнда с помощью Tickets. Хостинги разные были — проблема везде одна. Логическим/эмпирическим путём пытался сообразить откуда ноги растут — х его знает. Первый раз такое
что-то было подобное, но хоть убей не помню решение проблемы, обязательно сообщу если вспомню, помню только что в админку пускало с логином и пустым полем пароля)
Да, встречал несколько постов, где говорили, что админка пускает без пароля. У меня, этот способ не заработал, конечно (см. выше — проблема была в другом), но ведь чёрт возьми! Как так? Система пускает в админ.панель тупо по логину? Без пароля? И это реально так бывало? Достаточно знать логин админа? Это ведь какая-то особенная жесть, если такое дело вдруг на рабочем сайте обнаружится
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.