Авторизация, интеграция и прочие прелести

Я уже писал (и не только я), что иногда возникает желание к уже работающему сайту прикрутить социалку. Если речь идет о форуме или еще каком-то ресурсе, где уже есть регистрация, авторизация, то это отдельный разговор, как такое замутить. Но может быть и так, что возникает желание прикрутит ЛС к сайту, где регистрации не было, либо она была примитивной и ею можно пожертвовать. В таком случае разумней использовать систему регистрации/авторизации из ЛС. Немного поковырялся в коде, и вот что накопал (если что навру, пусть меня гуру поправят).

При входе в ЛС в куках создается переменная с именем 'key'. Поэтому из стороннего PHP-кода можно проверять, существует ли $_COOKIE['key']. И если есть, то всю инфу о юзере можно получить из базы из таблицы 'prefix_user' примерно так:


SELECT * FROM prefix_user WHERE user_key='{$_COOKIE['key']}'


В примере кода ниже никакого запроса нет, просто выводится ключ, если он есть:

<?
if (isset($_COOKIE['key'])) {
?>
  User Key: <?=$_COOKIE['key'];?> | <a href="/community/login/exit/">Выйти</a>
<?
} else {
?>
<form action="/community/login/" method="POST">
  <h3>Авторизация</h3>
  <label for="login">Логин или e-mail</label>
  <input type="text" class="input-text" name="login" id="login-input" /><br />

  <label for="password">Пароль</label> 
  <input type="password" name="password" class="input-text" /><br />

  <label for="" class="input-checkbox">
  <input type="checkbox" name="remember" checked />Запомнить меня</label><br />

  <input type="hidden" name="submit_login">
  <button type="submit" ">Войти</button>
</form>
<?
}
?>

PS Показан пример для варианта, когда ЛС живет не в корне, а в папке community

PPS ВНИМАНИЕ! SQL-запрос приводится в качестве очень упрощенного примера! Непосредственное его использование на рабочем сайте может создать угрозу безопасности! Как верно замечено комментаторами ниже, нельзя совать в запрос, что попало без тщательной проверки!

UPD Вышесказанное действительно, если при входе юзера стоит галка «Запомнить меня» и мы хотим воспользоваться этой опцией. А вообще надо проверять сессионную переменную 'user_id' (и в prefix_user можно найти запись по соотвествующему полю).

23 комментария

avatar
SELECT * FROM prefix_user WHERE user_key='{$_COOKIE['key']}'

меня одного смущает отсутствие проверки принимаемых от пользователя данных?
avatar
данные получаются из базы, а не от пользователя. туда они уже попадают проверенными.
avatar
куки можно любые подставить так же как и GET переменные, например
avatar
куки принимаются от пользователя, а не от базы и совать всякую гадость в рот непроверенные данные в базу не есть гуд

понятно, что пример сильно упрощен, но прописать для особо рьяных фразу «прямо так делать не нужно — проверяйте передаваемые юзером данные» в посте, ИМХО, стоит
avatar
Вы показали sql-запрос, я вам ответил исходя из его логики. Вероятность совпадения поддельного ключа с чьим-то реальным очень мала.
avatar
не, ты фишку не просек :-] если от юзера в $_COOKIE прилетит нечто похожее на '; DELETE FROM prefix_user; /*
или '; INSERT INTO prefix_administrators ('user_id') VALUES ('НАШ_ЮЗЕР_ИД'); /* или еще чтонибудь в этом духе, то будет ох и ах ;-)

и это называется SQL-инъекция
avatar
Ты оказался чуть-чуть быстрее :-))
avatar
а то :)) сразу и концепт кода привел, чтобы топик-стартер заценил всю мощь написанного им кода.

2 avadim: только бекап сделай перед проверкой, а то стремна будет =]
avatar
Видимо мы параллельно думаем, земляк :-D
avatar
хыы, а ведь действительно :))
avatar
Проверка — дело самом собой разумеющееся. Я увидел запрос и решил, что имелся ввиду процитированный код, который сам по себе безопасен. При условии, что использующийся в нём ключ действительно является ключом.

Прочёл первую половину топика и перешёл к комментариям :)
avatar
А здесь Mitos не о совпадении говорит, а о том, что в значения куки можно сунуть SQL-инъекцию и она без проверки наделает делов.
avatar
я об SQL injection, а не о совпадениях

и к тому, что в пост необходимо добавить фразу типа "$_COOKIE['key'] необходимо предварительно проверить и удостовериться, что там именно ключ, а не код". Так сказать «во избежание» нерадивых «интеграторов»…
avatar
во, набежали и пояснили :)
avatar
В коде, кроме вывода ключа в хтмл-код, с ним никаких других манипуляций не проводится, то в данном случае говорить о нерадивости интеграторов некорректно. Обычный proof of concept.

Тем не менее, радует, что тема безопасности не оставляет равнодушными наших коллег :)
avatar
… всех и сразу :-))))
avatar
Спасибо за замечание, коллеги! Ясень пень, SQL-инъекции никто не отменял, и явно так делать не стоит. Понятно, что я всего лишь показал ход мыслей, но не подумал, что кто-то может слишком буквально это воспринять. А поэтому дополнил топик предупреждением, что так делать нельзя. :)
avatar
Кстати, было бы лучше, если бы имя ключа в конфиге задавалось. А то мало ли — в исходном коде сайта, к которому ЛС прикручивается, могут уже использоваться куки с тем же именем.
avatar
Так кто нить с какой нить другой CMS интегрировал? То есть единую авторизацию делал?
avatar
С настоящей CMS не интегрировал, но к одному из сайтов прикрутил ЛС и использую авторизацию ЛС для разруливания прав юзеров по всему сайту.
avatar
Можно пример хоть в личку?
avatar
Когда выложу в открытый доступ — кину, пока тестирую локально. Но общий принцип описан выше: если есть в сессии user_id — пляшу от него, нет — смотрю, нет ли в куках ключа. Если и ключа нет — даю форму для ввода логина-пароля, а сабмит формы идет на авторизацию ЛС.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.