У меня есть веб-сайт PHP / MySQL (веб-сайт 1), который имеет систему входа в систему, которая запрашивает только ПИН-код (только длинную числовую строку). У пользователя есть 2 способа входа с этим кодом:
Пока здесь все работает нормально.
Теперь пришёл вопрос. Я хотел бы знать, если при использовании второго метода, описанного выше, возможно ли разрешить только вход в систему (при условии, что PIN-код правильный) ТОЛЬКО если эта ссылка была нажата на определенном веб-сайте.
Как это работает сейчас, любой, у кого есть ссылка, может использовать ее для входа на веб-сайт 1. Я хочу предотвратить это, я хочу, чтобы это произошло, если по этой ссылке щелкнули выиграть веб-сайт 2.
Идея состоит в том, чтобы «обнаружить» ссылающийся веб-сайт в функции входа в систему и разрешить его, только если он соответствует URL (или любому другому уникальному идентификатору) веб-сайта 2.
Если использование «простой» ссылки не позволит этого, что не будет проблемой, я гибко отношусь к тому, как я могу использовать это, но в конце концов это должно быть что-то, что означало бы только щелчок для пользователи на сайте 2.
РЕДАКТИРОВАТЬ
Я думаю, что это хорошо, потому что некоторые комментарии / ответы говорят о безопасности выполнения этого (что, конечно, здорово). Основная причина сделать это состоит в том, чтобы «заставить» пользователей посетить веб-сайт 2 перед переходом на веб-сайт 1. В основном, чтобы они не могли ввести этот URL-адрес в свой браузер и войти на веб-сайт 1, я хочу иметь возможность использовать только этот ссылку, если они нажимают на нее с веб-сайта 2. Я объясняю это, потому что безопасность здесь не имеет большого значения, если несколько опытных пользователей могут обойти любой метод, который я использую, это не имеет большого значения, более важно, чтобы метод был настолько простым насколько это возможно реализовать на веб-сайте 2 (так как я не запускаю этот веб-сайт, и мне нужно будет попросить людей там сделать все необходимое).
Я думаю, что вы ищете вариант единого входа. Это метод, в котором аутентификация на одном сайте распознается прозрачно на другом. Вот как это работает в вашем случае.
Обычно у вас есть ссылка на site2.com, например:
Тем не менее, site1.com не может сказать от реферера, с какого сайта он действительно пришел, так как его можно легко подделать. Конечно, это может не иметь значения для вашего варианта использования, если вы хотите только простой уровень безопасности. Но если вы хотите что-то лучшее, читайте дальше!
Вы можете использовать систему хеширования и общий секрет, чтобы создать что-то, что может быть получено только из одного источника. Оба сайта имеют один и тот же общий секрет, который хранится в файле. Мы назовем это $sharedSecret
, Алгоритм выглядит так:
$hash = hashFunction($pin . $sharedSecret);
Тогда вы можете сделать это на site2.com:
<a
href="http://site1.com/login.php?pin=<?php echo (int) $pin ?>&hash=<?php echo $hash ?>"alt="Authenticated link">
Когда site1.com видит его, он может сразу получить PIN-код, повторить алгоритм и проверить, действительно ли хеш получен с site2.com. Если у вас есть несколько ссылающихся сайтов, то site1.com должен хранить отдельный секрет для всех из них, а затем он может безопасно проверить реферер, чтобы увидеть, какой из них он должен загрузить.
Общий секрет должен быть достаточно существенным, чтобы его невозможно было угадать; Я склоняюсь к примерно 40-60 символов.
Тем не менее, остальным недостатком этого плана является то, что кто-то может посетить site2.com и украсть у них ссылку, и она все равно будет работать, при условии, что они также готовы были подделать реферала каждый раз, когда хотели получить доступ. Поэтому может быть полезно добавить временную метку в алгоритм:
// The time is rounded to the nearest 500 seconds, to account for
// out of sync clocks. Adjust this depending on how long you want links to
// remain active for
$time = floor(time() / 500) * 500;
$hash = hashFunction($pin . $sharedSecret . $time);
Затем на site1.com вы должны вычислить два хэша:
floor(time() / 500) * 500
floor(time() / 500) * 500 - 500
Если предоставленный хеш совпадает, разрешите ссылке разблокировать контент. Это объясняет возможность того, что время перешло границу +/- 500 между одним сервером и следующим.
Я не упомянул конкретную функцию хеширования здесь. SHA256 должно быть хорошо, но учтите, я не криптограф. Если вы снова хотите повысить безопасность, возможно, стоит проверить, чтобы кто-то не переборщил систему, наводнив вашу систему догадками — хотя через Интернет вряд ли стоит их пытаться.
Проблема многогранна. $ _SERVER [‘HTTP_REFERER’] доступен для PHP, но может быть подделан или опущен и считается ненадежным.
Междоменные файлы cookie также являются проблемой; Я понимаю, что это возможно, но пока не нашел времени для его реализации (у нас есть вариант использования на работе). В любом случае, cookie-файлы также вполне пригодны для использования.
Возможно, лучше всего было бы, чтобы точка ссылки на «сайте А» указывала на ресурс также на «сайте А», который устанавливает случайный ключ / токен и метку времени в общую базу данных и перенаправляет браузер на «сайт Б» с этим маркер. Получающая страница на «сайте B» затем проверит наличие ключа / токена в строке GET, проверит его наличие в базе данных и, возможно, сопоставит данные User-Agent и Referer и проверит, что время было в пределах $ smallnum секунд. после ввода метки времени для этого ключа / токена.
Я собираюсь опубликовать этот ответ, который я получил благодаря другим ответам / комментариям других пользователей SO. Я думаю, что это довольно простой метод (простота хороша в этом случае), и что он должен работать, но, конечно, если у него есть какой-то большой недостаток, было бы здорово узнать 🙂
Как я уже говорил в OP, безопасность (с точки зрения того, что какой-то опытный пользователь обходит это и использует ссылку напрямую, а не с веб-сайта 2), здесь не такая уж большая проблема, мы можем иметь дело с небольшим количеством исключений.
Вот идея:
http://myURL.com/process_login_request.php?pin=123456789&token=abc123def456
process_login_request.php
Используя ту же функцию, которая использовалась для генерации токена на веб-сайте 2, сгенерирует количество токенов за последние X секунд (скажем, 10 секунд), используя PIN-код и временные метки за последние 10 секунд.Я думаю, что это легче осуществить, чем объяснить, хотя. Идея в основном заключается в том, что мы используем временные метки за короткий промежуток времени (время между тем, когда пользователь «щелкает» по ссылке, которая должна привести его на сайт 1, и временем, которое он фактически попадает на сайт 1). Я сказал 10 секунд, но мы могли бы увеличить это по мере необходимости, если 10 секунд слишком мало (что, я думаю, не должно быть).