Разрешить вход на веб-сайт только в том случае, если запрос поступает с другого конкретного веб-сайта

У меня есть сайт PHP / MySQL (веб-сайт 1), в котором есть система входа в систему, которая запрашивает только PIN-код (просто длинная числовая строка). У пользователя есть два способа входа в систему с помощью этого кода:

  1. Перейдите на страницу входа в систему 1 и введите код в обычной форме входа
  2. Нажав на веб-сайт 2 по ссылке, которая несет свой ПИН-код в качестве значения GET. Ссылка имеет формат http://myURL.com/login.php?pin=123456789 . Это просто вызывает функцию, которая получает ПИН в качестве параметра и обрабатывает логин. Веб-сайт 2 находится в другом домене / сервере, чем веб-сайт 1 .

Пока здесь все работает нормально.

Теперь придет вопрос. Я хотел бы знать, если при использовании второго метода, описанного выше, если возможно разрешить вход в систему (при условии, что PIN-код правильный) ТОЛЬКО, если эта ссылка была нажата на определенном веб-сайте .

Как это работает сейчас, любой, у кого есть ссылка, может использовать его для входа на веб-сайт. 1. Я хочу предотвратить это, я хочу, чтобы это произошло, если эта ссылка была нажата на win website 2.

Идея заключалась бы в том, чтобы «обнаружить» ссылающийся веб-сайт в функции входа и разрешить его только в том случае, если он соответствует URL (или любому другому уникальному идентификатору) веб-сайта 2.

Если использование «простой» ссылки не позволит этого, это не будет проблемой, я гибко отношусь к тому, как я мог бы использовать для этого, но в конечном итоге это должно было быть чем-то, что означало только щелчок для пользователей на веб-сайте 2.

РЕДАКТИРОВАТЬ

Я думаю, что хорошо добавить это, поскольку некоторые комментарии / ответы говорят о безопасности этого (что, конечно же, замечательно). Основная причина заключается в том, чтобы «заставить» пользователей посещать веб-сайт 2 перед тем, как перейти на веб-сайт. В принципе, они не могут ввести этот URL-адрес в свой браузер и войти на сайт 1, я хочу только использовать этот ссылку, если они нажимают на нее с сайта 2. Я объясняю это, потому что безопасность здесь не является огромным фактором, если несколько самоуверенных пользователей могут обойти любой метод, который я реализую, это не очень важно, тем более важно, чтобы метод был простым как можно реализовать на веб-сайте 2 (поскольку я не запускаю этот веб-сайт, и мне нужно будет попросить людей сделать все, что необходимо).

Solutions Collecting From Web of "Разрешить вход на веб-сайт только в том случае, если запрос поступает с другого конкретного веб-сайта"

Я думаю, вы ищете вариант Single Sign On. Это метод, при котором аутентификация на одном сайте распознается прозрачно в другом. Вот как это работает в вашем случае.

Обычно у вас есть ссылка в site2.com следующим образом:

http://site1.com/login.php?pin=123456789

Тем не менее, site1.com не может сказать от реферера, на каком сайте он действительно появился, поскольку он может быть тривиально фальсифицирован. Конечно, это может не иметь значения для вашего случая использования, если вам нужен только простой уровень безопасности. Но если вы хотите что-то получше, читайте дальше!

Вы можете использовать систему хэширования и общий секрет, чтобы создать что-то, что может быть получено только из одного источника. Оба сайта имеют один и тот же общий секрет, хранящийся в файле. Мы будем называть это $sharedSecret . Алгоритм выглядит следующим образом:

 $hash = hashFunction($pin . $sharedSecret); 

Затем вы можете сделать это на сайте site2.com:

 <a href="http://site1.com/login.php?pin=<?php echo (int) $pin ?>&amp;hash=<?php echo $hash ?>" alt="Authenticated link" > 

Когда site1.com видит это, он может сразу получить PIN-код, повторить алгоритм и проверить, что хэш действительно появился с сайта2.com. Если у вас есть несколько ссылочных сайтов, то site1.com должен хранить отдельный секрет для всех из них, а затем он может надежно проверить реферер, чтобы посмотреть, какой из них он должен загрузить.

Общий секрет должен быть достаточно значительным, чтобы его нельзя было догадаться; Я, как правило, занимаю около 40-60 символов.

Однако оставшийся недостаток в этом плане состоит в том, что кто-то может посетить сайт2.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); 

Затем на сайте site.com вы должны вычислить два хэша:

  • Один для floor(time() / 500) * 500
  • Один для floor(time() / 500) * 500 - 500

Если предоставленный хэш соответствует, разрешите ссылку разблокировать контент. Это объясняет, что время прошло через границу +/- 500 между одним сервером и следующим.

Я не упомянул о конкретной функции хэширования здесь. SHA256 должно быть хорошо, но обратите внимание, что я не криптограф. Если вы хотите снова получить дополнительную защиту, может быть стоит проверить, чтобы кто-то не грубо заставлял систему, наводя систему на догадки – хотя через Интернет вряд ли стоит их пытаться.

Проблема многогранна. $ _SERVER ['HTTP_REFERER'] доступен для PHP, но может быть подделан или опущен и считается ненадежным.

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

Вероятно, лучшим вариантом было бы, чтобы точка ссылки на «Site A» указывала на ресурс также на «Site A», который устанавливает случайный ключ / токен и временную метку в общую базу данных и отсылает браузер к «сайту B» с тем, что маркер. Затем страница приема на «сайте B» проверяет наличие ключа / токена в строке GET, проверяет наличие в базе данных и, возможно, соответствует данным User-Agent and Referer и проверяет, что время было в пределах $ smallnum seconds после записи временной метки для этого ключа / токена.

Я собираюсь опубликовать этот ответ, который я получил благодаря другим ответам / комментариям, сделанным другими пользователями SO. Я думаю, что это довольно простой метод (простота в этом случае хороша), и что он должен работать, но, конечно, если у него есть какой-то большой недостаток, мне было бы хорошо знать 🙂

Как я уже говорил в OP, безопасность (с точки зрения некоторого опытного пользователя, который обошел это и используя ссылку напрямую, а не с сайта 2), здесь не очень много, мы можем иметь дело с небольшим количеством исключений.

Вот идея:

  • Дайте пользователю на веб-сайте 2 ссылку на функцию в том же домене
  • Эта функция захватывает PIN-код (т. Е. 1234567890), который будет иметь каждый пользователь, и текущую временную метку (т. Е. 1417812842), создавая токен, используя эти 2 значения, используя другую функцию, которую будут знать оба веб-сайта (например, хэширование с солью )
  • Создайте перенаправление с веб-сайта 2 на веб-сайт 1 с URL-адресом, который включает в себя ПИН-код и токен, например: http://myURL.com/process_login_request.php?pin=123456789&token=abc123def456
  • Функция в process_login_request.php , используя ту же функцию, которая была использована для создания токена на веб-сайте 2, будет генерировать несколько токенов за последние X секунд (скажем, 10 секунд), используя ПИН и временные метки за последние 10 секунд.
  • Если какой-либо из сгенерированных токенов соответствует принятому токену, значит, что запрос был в порядке, и мы разрешаем вход

Я думаю, что это легче реализовать, чем объяснять. Идея в основном заключается в том, что мы используем временные метки за короткий промежуток времени (время между пользователем «нажимает» ссылку, которая должна отнести его на сайт 1 и время, когда он на самом деле приземляется на веб-сайт 1). Я сказал 10 секунд, но мы могли бы увеличить это, если необходимо, если 10 секунд слишком коротки (что, я думаю, этого не должно быть).